Cod sursa(job #3264911)

Utilizator Cezar2009Cezar Mihai Titihazan Cezar2009 Data 25 decembrie 2024 18:23:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
//https://infoarena.ro/problema/lca
#include <iostream>
#include <fstream>
#include <vector>
#include <utility>
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

vector<pair<int, int>> v;
vector<pair<int, int>> rez;
vector<vector<int>> gr;
vector<int> b, first;
int mat[20][200010], l[200010];

void dfs(int vf) 
{
    b[vf] = 1;
    if (first[vf] == -1) 
    {
        first[vf] = rez.size();
    }
    rez.emplace_back(vf, v[vf].second);

    for (int x : gr[vf]) 
    {
        if (!b[x]) {
            dfs(x);
            rez.emplace_back(vf, v[vf].second);
        }
    }
}

void build() 
{
    int n = rez.size();
    for (int i = 0; i < n; ++i) 
    {
        mat[0][i] = i;
    }

    for (int i = 1; (1 << i) <= n; ++i)
    {
        for (int j = 0; j + (1 << i) <= n; ++j) 
        {
            int left = mat[i - 1][j];
            int right = mat[i - 1][j + (1 << (i - 1))];
            mat[i][j] = (rez[left].second < rez[right].second) ? left : right;
        }
    }

    l[1] = 0;
    for (int i = 2; i <= n; ++i)
    {
        l[i] = l[i / 2] + 1;
    }
}

int rezultat(int lq, int rq) 
{
    int log = l[rq - lq + 1];

    if (rez[mat[l[rq - lq + 1]][lq]].second < rez[mat[l[rq - lq + 1]][rq - (1 << (l[rq - lq + 1])) + 1]].second)
        return mat[l[rq - lq + 1]][lq];
    else
        return mat[l[rq - lq + 1]][rq - (1 << (l[rq - lq + 1])) + 1];
}

int main() 
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n, m, i, q, p;
    fin >> n >> m;

    v.resize(n + 1);
    b.resize(n + 1);
    gr.resize(n + 1);
    first.resize(n + 1, -1);

    v[1].first = 0;
    v[1].second = 0;

    for (i = 2; i <= n; ++i)
    {
        fin >> v[i].first;
        v[i].second = v[v[i].first].second + 1;

        gr[i].push_back(v[i].first);
        gr[v[i].first].push_back(i);
    }

    dfs(1);

    build(); 

    for (i = 1; i <= m; ++i) {
        fin >> q >> p;

        int qp = min(first[q], first[p]);
        int pp = max(first[q], first[p]);

        fout << rez[rezultat(qp, pp)].first << "\n";
    }

    return 0;
}