Cod sursa(job #719220)

Utilizator iuli1505Parasca Iuliana iuli1505 Data 21 martie 2012 16:58:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.26 kb
#include<cstdio>
#include<vector>
#define nmax 100010
using namespace std;
int n,m,val,x,y,nr;
int e[2*nmax],niv[2*nmax],lung[2*nmax],p[nmax],RMQ[20][2*nmax];
vector<int> g[nmax];
void rmq(),dfs(int,int);
int lca(int,int);
int main()
{
	int i;
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d%d", &n,&m);
	for(i=2;i<=n;i++)
	{
		scanf("%d", &val);
		g[val].push_back(i);
	}
	dfs(1,0);
	rmq();
	for(i=1;i<=m;i++)
	{
		scanf("%d%d", &x, &y);
		printf("%d\n", lca(x,y));
	}
	return 0;
}
void rmq()
{
	int i,j;	
	for(lung[1]=0,i=2;i<=nr;i++)
		lung[i]=lung[i/2]+1;
	for(i=1;i<=nr;i++)
		RMQ[0][i]=i;
	for(i=1;(1<<i)<nr;i++)
		for(j=1;j<=nr-(1<<i);j++)
			niv[RMQ[i-1][j]]<niv[RMQ[i-1][j+(1<<(i-1))]]?RMQ[i][j]=RMQ[i-1][j]:RMQ[i][j]=RMQ[i-1][j+(1<<(i-1))];
}
void dfs(int nod, int nivel)
{
	e[++nr]=nod;
	niv[nr]=nivel;
	p[nod]=nr;
	for(vector<int>::iterator it=g[nod].begin();it!=g[nod].end();it++)
	{
		dfs(*it,nivel+1);
		e[++nr]=nod;
		niv[nr]=nivel;
	}
}
int lca(int x, int y)
{
	int dif,s,X,Y,aux;
	X=p[x];
	Y=p[y];
	if(X>Y)
	{
		aux=X;
		X=Y;
		Y=aux;
	}
	dif=Y-X+1;
	s=RMQ[lung[dif]][X];
	if(niv[s]>niv[RMQ[lung[dif]][X+dif-(1<<lung[dif])]])
		s=RMQ[lung[dif]][X+dif-(1<<lung[dif])];
	return e[s];
}