Pagini recente » Cod sursa (job #1952885) | Cod sursa (job #454484) | Cod sursa (job #1532040) | Cod sursa (job #1639846) | Cod sursa (job #1060845)
// 10.12.2013
// Lowest Common Ancestor
// <O(N logN)> Pre-processing time
// <O(logN)> Query time
// I create the matrix M[1..N][0..logH] where M[i][j] represents the 2^j-th ancestor
// of node i
using namespace std;
#include<fstream>
#include<cmath>
#include<vector>
#include<algorithm>
ifstream cin("lca.in");
ofstream cout("lca.out");
const int MAXN=100001;
vector<int> v[MAXN]; // v[i][j] will point to the j-th son of node i
int A[MAXN]; // A[i] will point to the father of i
int L[MAXN]; // L[i] will have the level of node i
int M[MAXN][30];
int H;
void dfs(int i){
for(unsigned j=0;j<v[i].size();j++){
L[v[i][j]]=L[i]+1;
dfs(v[i][j]);
}
return;
}
int main(){
int N,Q;
cin>>N>>Q;
for(int i=2;i<=N;i++){
cin>>A[i];
v[A[i]].push_back(i);
}
// I will assume that the root of the tree is node 1
L[1]=1;
dfs(1); //for setting the level of each node and calculating the depth of the tree
H=*max_element(L+1,L+N+1);
for(int i=1;i<=N;i++)
M[i][0]=A[i]; //base case, the ancestor directly above this node
for(int j=1;(1<<j)<=H;j++)
for(int i=1;i<=N;i++)
if(M[M[i][j-1]][j-1])
M[i][j]=M[M[i][j-1]][j-1];
// The query Part
while(Q--){
int x,y;
cin>>x>>y;
// First to get the nodes on the same level
if(L[x]>L[y]){
int lv=L[x]-L[y];
for(int j=0;(1<<j)<=lv;j++)
if(lv & (1<<j))
x=M[x][j];
}else if(L[y]>L[x]){
int lv=L[y]-L[x];
for(int j=0;(1<<j)<=lv;j++)
if(lv & (1<<j))
y=M[y][j];
}
// Now I use binary search to get the LCA
while(true){
int s=0;
while(M[x][s]!=M[y][s])
s++;
if(!s) break;
s--;
x=M[x][s];
y=M[y][s];
}
cout<<( x==y ? x : M[x][0])<<'\n';
}
return 0;
}