Pagini recente » Cod sursa (job #212069) | Cod sursa (job #2428088) | Cod sursa (job #339249) | Cod sursa (job #15002) | Cod sursa (job #3155804)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q;
vector<vector<int>> dp, children;
vector<int> D;
void dfs(int nod, int depth){
if(nod != 1){
int p=2;
for(int k=1; p<=depth; k++){
dp[nod][k] = dp[dp[nod][k-1]][k-1];
p *= 2;
}
}
D[nod] = depth;
for(int child:children[nod])
dfs(child, depth+1);
}
int level(int x, int l){
int sol = x;
int p = l - D[x], k=0;
while(p and sol > 0){
if(p % 2)
sol = dp[sol][k];
p /= 2;
k++;
}
return (sol > 0 ? sol : 0);
}
int querry(int a, int b){
if(D[a] < D[b])
b = level(b, D[a]);
else a = level(a, D[b]);
int l = 0, r = D[a], sol = -1;
while(l <= r){
int mid = (l + r) / 2;
int nod = level(a, mid);
if(nod == level(b, mid))
sol = nod, l = mid + 1;
else r = mid - 1;
}
return sol;
}
int main(){
cin>>n>>q;
dp.resize(n+1, vector<int>(20, -1));
children.resize(n+1);
D.resize(n+1);
for(int i=2; i<=n; i++){
cin>>dp[i][0];
children[dp[i][0]].push_back(i);
}
dfs(1, 0);
// cout<<level(5, 2);
while(q--){
int a, b;
cin>>a>>b;
cout<<querry(a, b)<<"\n";
}
return 0;
}