Cod sursa(job #2236954)

Utilizator lupulescu2001Lupulescu Vlad lupulescu2001 Data 31 august 2018 01:40:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.27 kb
#include <fstream>
#include <vector>
using namespace std;

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

int N,Q,Size,Euler[200005],Lg[200005],LV[100005], First[100005],RMQ[20][200005];
vector<int> G[100005];

int LVL(int X,int Y){
    if(LV[X]<LV[Y])
       return X;
    return Y;
}

void DFS(int Nod){
    Size++;
    Euler[Size]=Nod;
    First[Nod]=Size;
    for (int i=0;i<G[Nod].size();i++) {
        LV[G[Nod][i]] = LV[Nod]+1;
        DFS(G[Nod][i]);
        Size++;
        Euler[Size]=Nod;
    }
}

void Construire() {
    for (int i=2;i<=Size;i++)
        Lg[i]=Lg[(i/2)]+1;
    for (int i=1;i<=Size;i++)
        RMQ[0][i]=Euler[i];
    for (int i=1;(1<<i)<=Size;i++)
        for (int j=1;j<=Size-(1<<i)+1;++j)
            RMQ[i][j]=LVL(RMQ[i-1][j],RMQ[i-1][j+(1<<(i-1))]);
}

int LCA(int X, int Y) {
    X=First[X];
    Y=First[Y];
    if(X>Y)
        swap(X,Y);
    int Exponent=Lg[Y-X];
    return LVL(RMQ[Exponent][X],RMQ[Exponent][Y-(1<<Exponent)+1]);
}

int main() {
    fin >> N >> Q;
    for (int i=2;i<=N;i++){
        int F;
        fin>>F;
        G[F].push_back(i);
    }
    DFS(1);
    Construire();
    while (Q--) {
        int X,Y;
        fin>>X>>Y;
        fout<<LCA(X,Y)<<"\n";
    }
    return 0;
}