Cod sursa(job #2417593)

Utilizator carreraPaul Achim carrera Data 30 aprilie 2019 14:44:47
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 kb
#include <bits/stdc++.h>

using namespace std;

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

const int N_MAX = 800000 + 5;
const int INF = 0x3f3f3f3f;

int t[N_MAX], n, m, eu[N_MAX], ne, first[N_MAX], level[N_MAX];

int rmq[100][N_MAX];



vector<int> vec[N_MAX];

void euler(int nod, int nivel){
    eu[++ne] = nod;
    level[ne] = nivel;
    if(!first[nod])
        first[nod] = ne;
    for(auto v : vec[nod]){
        euler(v, nivel+1);
        eu[++ne] = nod;
        level[ne] = nivel; // nivel + 1
    }
}

void init(){
    for(int i = 1; i <=ne; ++i)
        rmq[0][i] = i;
    for(int power = 1; (1<<power) <= ne; ++power)
        for(int i = 1; i + (1<<power) - 1 <= ne; i++)
            if(level[rmq[power-1][i]] < level[rmq[power-1][i + (1<<(power-1))]])
               rmq[power][i] = rmq[power-1][i];
            else
                rmq[power][i] = rmq[power-1][i + (1<<(power-1))];
}

int solve(int aa, int bb){
    aa = first[aa];
    bb = first[bb];

    if(aa > bb)
        swap(aa,bb);

    int dim = bb - aa + 1;
    int power = log2(dim);

    int indice;

    if(level[rmq[power][aa]] <= level[rmq[power][bb - (1<<(power)) + 1]])
               indice = rmq[power][aa];
            else
               indice = rmq[power][bb - (1<<(power)) + 1];

    return eu[indice];
}

int main()
{
    fin >> n >> m;
    for(int i = 2; i <=n; ++i){
        fin >> t[i];
        vec[t[i]].push_back(i);
    }

    euler(1, 1);

    init();

    while(m--){
        int aa, bb;
        fin >> aa >> bb;
        fout << solve(aa, bb) << "\n";
    }

    return 0;
}