Pagini recente » Cod sursa (job #1471921) | Cod sursa (job #689998) | Cod sursa (job #1867682) | Cod sursa (job #2101655) | Cod sursa (job #2798737)
#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';
}
}