Cod sursa(job #385416)

Utilizator jeanFMI - Petcu Ion Cristian jean Data 22 ianuarie 2010 18:16:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.16 kb
#include<stdio.h>
#include<vector>
#define Nmax 100010
using namespace std;

int M[25][Nmax<<1],E[Nmax<<1],H[Nmax<<1],i,j,x,y,n,m,k,poz[Nmax],aux;
vector<int> V[Nmax];

void dfs(int nod,int h)
{
	E[++k]=nod;
	H[k]=h;
	poz[nod]=k;
	
	int N=V[nod].size(),t;
	
	for(t=0;t<N;t++)
	{
		dfs(V[nod][t],h+1);
		E[++k]=nod;
		H[k]=h;
	}
}	


void rmq()
{
	int j,i;
	
	for(i=1;i<=k;i++)
		M[0][i]=i;
	
	for(j=1; (1<<j) <= k ; j++)
		for(i=1; i + (1<<j) -1 <= k; i++)
			if(H[M[j-1][i]] <= H[M[j-1][i+(1<<(j-1))]])
				M[j][i]=M[j-1][i];
			else M[j][i]=M[j-1][i+(1<<(j-1))];
}

int lca(int i, int j)
{
	int k=0,val=j-i+1,p;
	
	while(val!=1)
	{
		k++;
		val>>=1;
	}
	
	if( H[M[k][i]] <= H[M[k][j-(1<<k)+1]] )
		p=M[k][i];
	else p=M[k][j-(1<<k)+1];
	
	return E[p];
}

int main()
{
	
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	
	scanf("%d %d",&n,&m);
	
	for(i=2;i<=n;i++)
	{
		scanf("%d",&x);
		V[x].push_back(i);
	}
	
	dfs(1,0);
	rmq();
	for(i=1;i<=m;i++)
	{
		scanf("%d %d",&x, &y);
		
		x=poz[x];
		y=poz[y];
		
		if(x>y) {aux=x; x=y; y=aux;}
		
		printf("%d\n",lca(x,y));
		
	}
	return 0;
}