Cod sursa(job #794769)

Utilizator mihaiSimuSimu Mihai mihaiSimu Data 6 octombrie 2012 23:25:29
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.21 kb
#include <stdio.h>
#include <vector>
using namespace std;

vector< int > G[100005];

int E[200010],L[200010],F[100005];

int P[100005],ne=0;
int n,m1;
int m[200010][18],log2[200010];
void dfs(int node,int level){
	E[ne]=node;L[ne]=level;F[node]=ne;
	ne++;
	for(int i=0;i<G[node].size();i++){
		dfs(G[node][i],level+1);
		E[ne]=node;
		L[ne]=level;
		ne++;
	}
}

void preProcess(){
	log2[1]=0;
	for(int i=2;i<=ne;i++) log2[i]=log2[i/2]+1;
	for(int i=0;i<ne;i++){
		m[i][0]=i;
	}
	for(int j=1; 1<<j <=ne;j++)
		for(int i=0;i+(1<<j)-1  <ne;i++)
		{	if(L[m[i][j-1]]<=L[m[i+(1<<(j-1))][j-1]])
				m[i][j]=m[i][j-1];
				else
				m[i][j]=m[i+(1<<(j-1))][j-1];
		}
}

int rmq(int i,int j){
	int k=log2[j-i+1];
	if(L[m[i][k]]<L[ m[j-(1<<k)+1][k] ])
		return m[i][k];
		else
		return m[j-(1<<k)+1][k];
}	

int main(){

	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	int x,y;
	scanf("%d",&n);scanf("%d",&m1);
	for(int i=2;i<=n;i++){
		scanf("%d",&P[i]);
		G[P[i]].push_back(i);
	}
	
	dfs(1,0);
	preProcess();
	
	bool first=true;
	for(int i=0;i<m1;i++){
		scanf("%d %d",&x,&y);
		if(!first) printf("\n");
		first=false;
		printf("%d",E[ rmq( F[x],F[y] )]);
	}
	return 0;
}