Cod sursa(job #2839506)

Utilizator BalasaRaduBalasa Radu BalasaRadu Data 26 ianuarie 2022 00:25:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.38 kb

#include <bits/stdc++.h>
using namespace std;

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

const int dim=100009;

vector<int>v[dim];

int len,nivel[dim];
int euler[2*dim],aparitie[2*dim];

void DFS(int x,int tata){
    euler[++len]=x;
    nivel[x]=nivel[tata]+1;
    aparitie[x]=len;
    for(int y:v[x]){
        DFS(y,x);
        euler[++len]=x;
    }
}

int logaritm[2*dim];
int rmq[2*dim][30];

void generare(){
    for(int i=2;i<=len;i++){
        logaritm[i]=logaritm[i/2]+1;
    }
    for(int i=1;i<=len;i++){
        rmq[i][0]=i;
    }
    for(int j=1;(1<<j)<=len;j++){
        for(int i=1;i+(1<<j)-1<=len;i++){
            int l=rmq[i][j-1];
            int r=rmq[i+(1<<(j-1))][j-1];
            rmq[i][j]=(nivel[euler[l]]<nivel[euler[r]]) ? l : r;
        }
    }
}

int lca(int a,int b){
    a=aparitie[a];
    b=aparitie[b];
    if(a>b){
        swap(a,b);
    }
    int log=logaritm[b-a+1];
    int l=rmq[a][log];
    int r=rmq[b-(1<<log)+1][log];
    return (nivel[euler[l]]<nivel[euler[r]]) ? euler[l] : euler[r];
}

void find_lca(){
    DFS(1,0);
    generare();
}

signed main(){
    int n,q;
        fin>>n>>q;
    for(int i=2;i<=n;i++){
        int j;
        fin>>j;
        v[j].push_back(i);
    }
    find_lca();
    while(q--){
        int l,r;
        fin>>l>>r;
        fout<<lca(l,r)<<'\n';
    }
}