Cod sursa(job #2324120)

Utilizator DimaTCDima Trubca DimaTC Data 20 ianuarie 2019 11:58:21
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.15 kb
#include<bits/stdc++.h>
#define N 100005
using namespace std;

int E[2*N],L[2*N];
int rmq[2*N][18];
int F[N];
int LOG[2*N];
int k,n,m;
vector<int>V[N];

void DFS(int x, int lvl) {
    E[++k]=x;
    L[k]=lvl+1;
    F[x]=k;
    for (auto it: V[x]) {
        DFS(it, lvl+1);
        E[++k]=x;
        L[k]=lvl+1;
    }
}

int main() {
    ifstream cin("lca.in");
    ofstream cout("lca.out");
    cin>>n>>m;
    for (int i=2; i<=n; ++i) {
        int x; cin>>x;
        V[x].push_back(i);
    }

    DFS(1,0);

    for (int i=2; i<=N-5; ++i) LOG[i]=LOG[i>>1]+1;
    for (int i=1; i<=k; ++i) rmq[i][0]=i;

    for (int j=1; (1<<j)<=k; ++j) {
        for (int i=1; i+(1<<j)-1<=k; ++i) {
            if (L[rmq[i][j-1]]<L[rmq[i+(1<<(j-1))][j-1]]) rmq[i][j]=rmq[i][j-1];
            else rmq[i][j]=rmq[i+(1<<(j-1))][j-1];
        }
    }

    while (m--) {
        int a,b; cin>>a>>b;
        if (F[a]>F[b]) swap(a,b);
        a=F[a]; b=F[b];
        int l=b-a+1;
        int k=LOG[l];
        if (L[rmq[a][k]]<L[rmq[b-(1<<k)+1][k]]) cout<<E[rmq[a][k]]<<'\n';
        else cout<<E[rmq[b-(1<<k)+1][k]]<<'\n';
    }

    return 0;
}