Cod sursa(job #2798737)

Utilizator BalasaRaduBalasa Radu BalasaRadu Data 11 noiembrie 2021 19:52:50
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.48 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;
int euler[2*dim];///parcurgerea euler
int nivel[2*dim];///nivelul fiecarui element din parcurgerea euler
int aparitie[2*dim];///o aparitie in parcurgerea euler a ficarui nod

int n,m;

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

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

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[l]<nivel[r]) ? l : r;
        }
    }
}

int lca(int a,int 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[l]<=nivel[r]) ? l : r;
}

signed main(){
        fin>>n>>m;
    for(int x=2;x<=n;x++){
        int y;
        fin>>y;
        v[y].push_back(x);
    }

    dfs(1,0);
    generare();
    while(m--){
        int l,r;
        fin>>l>>r;
        fout<<euler[lca(aparitie[l],aparitie[r])]<<'\n';
    }
}