Cod sursa(job #677763)

Utilizator BarracudaFMI-Alex Dobrin Barracuda Data 10 februarie 2012 16:53:08
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.14 kb
#include<cstdio>
#include<vector>
#define Nmax 100002
#define Mmax 2000002
using namespace std;
int eul[3*Nmax],niv[Nmax],PrimaAp[Nmax],r[20][Nmax],p[Nmax],a,i,j,nd,n,m;
vector<int>G[Nmax];
void read(){
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n;i++){
		scanf("%d",&nd);
		G[nd].push_back(i);
	}
}
int min(int a,int b){
	if(a<b)
		return a;
	return b;
}
void dfs(int nod){
	eul[++a]=nod;
	PrimaAp[nod]=a;
	for(int i=0;i<G[nod].size();++i){
		dfs(G[nod][i]);
		eul[++a]=nod;
	}
}
void rmq(){
	for(int i=1;i<=a;i++)
		r[0][i]=eul[i];
	
	for(int i=2;i<=a;i++)
		p[i]=p[i/2]+1;
	
	for(i=1 ;(1<<i) <=a;++i){
		
		for(j=1;j+ (1<<i)<=a;++j)
			
			r[i][j]=min(r[i-1][j],r[i-1][j+(1<<(i-1))]);
		
	}
}
void query(){
	int x,y,sol,len;
	for(i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		x=PrimaAp[x];
		y=PrimaAp[y];
		if(x<=y){
			len=p[y-x+1];
			sol=min(r[len][x],r[len][y+1-(1<<len)]);
		}
		else{
			len=p[x-y+1];
			sol=min(r[len][y],r[len][x+1-(1<<len)]);
		}
		printf("%d\n",sol);
	}
}
int main (){
	read();
	dfs(1);
	rmq();
	query();
	return 0;
}