Cod sursa(job #385488)

Utilizator GotenAmza Catalin Goten Data 22 ianuarie 2010 20:18:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.09 kb
#include<fstream.h>

int v[100100],w[100100],lg[200200],eu[200200],q,k,x,n,m,padre[100100],a[18][200200],y,lo,l,ln[200200],
	beg[100100],viz[100100];

void dfs(int nod, int depth)
{
	int t;
	eu[++k]=nod;
	if(!viz[nod])
	{
		viz[nod]=1;
		beg[nod]=k;
	}
	ln[k]=depth;
	t=lg[nod];
	while(t)
	{
		dfs(v[t],depth+1);
		t=w[t];
	}
	eu[++k]=padre[nod];
	ln[k]=depth-1;
}

int main()
{
	int i,j;
	ifstream f("lca.in");
	ofstream g("lca.out");
	f>>n>>m;
	for(i=2;i<=n;i++)
	{
		f>>x;
		padre[i]=x;
		v[++q]=i;
		w[q]=lg[x];
		lg[x]=q;
	}
	dfs(1,0);
	k--;
	lg[1]=0;
	lg[0]=-1;
	for(i=2;i<=k;i++)
		lg[i]=lg[i>>1]+1;
	for(i=1;i<=k;i++)
		a[0][i]=i;
	for(j=1;j<=lg[k];j++)
		for(i=1;j<=lg[k-i+1];i++)
			if(ln[a[j-1][i]]<ln[a[j-1][i+(1<<(j-1))]])
				a[j][i]=a[j-1][i];
			else
				a[j][i]=a[j-1][i+(1<<(j-1))];
	for(i=1;i<=m;i++)
	{
		f>>x>>y;
		x=beg[x];
		y=beg[y];
		if(x>y)
		{
			l=x;
			x=y;
			y=l;
		}
		l=y-x+1;
		lo=lg[l];
		if(ln[a[lo][x]]<ln[a[lo][y-(1<<lo)+1]])
			g<<eu[a[lo][x]]<<'\n';
		else
			g<<eu[a[lo][y-(1<<lo)+1]]<<'\n';
	}
	return 0;
}