Pagini recente » Borderou de evaluare (job #2172015) | Borderou de evaluare (job #3136369) | Cod sursa (job #671703) | Cod sursa (job #631800) | Cod sursa (job #2120323)
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
FILE *f = fopen("lca.in","r");
FILE *g = fopen("lca.out","w");
vector<int> G[100005];
vector<int> mark[100005];
int N,K,T;
int len;
int euler[200005];
bool U[100005];
bool vizU[100005];
int lvl[100005];
int RMQ[18][200005];
int Ta[100005];
int fst[100005];
int lst[100005];
void dfs(int nod,int tata){
lvl[nod] = lvl[tata] + 1;
Ta[nod] = tata;
euler[++len] = nod;
RMQ[0][len] = nod;
fst[nod] = len;
for(auto it:G[nod]){
if(it != tata){
dfs(it,nod);
euler[++len] = nod;
RMQ[0][len] = nod;
}
}
lst[nod] = len;
}
int better(int u,int v){
if(lvl[u] < lvl[v]){
return u;
}
return v;
}
void prelca(){
for(int i = 1;i <= 17;i++){
for(int j = 1;j <= len;j++){
if(j >= (1 << (i - 1))){
RMQ[i][j] = better(RMQ[i - 1][j],RMQ[i - 1][j - (1 << (i - 1))]);
}
}
}
}
int lca(int u,int v){
if(fst[u] > fst[v]){
swap(u,v);
}
int lg = 0;
while(fst[v] - fst[u] >= (1 << lg)){
lg++;
}
lg--;
return better(RMQ[lg][fst[v]],RMQ[lg][fst[u] + (1 << lg) - 1]);
}
int main(){
fscanf(f,"%d %d",&N,&K);
for(int i = 2;i <= N;i++){
int x;
fscanf(f,"%d",&x);
G[x].push_back(i);
G[i].push_back(x);
}
dfs(1,0);
prelca();
for(int i = 1;i <= K;i++){
int u,v;
fscanf(f,"%d %d",&u,&v);
fprintf(g,"%d\n",lca(u,v));
}
fclose(f);
fclose(g);
return 0;
}