Cod sursa(job #608084)

Utilizator Magnuscont cu nume gresit sau fals Magnus Data 14 august 2011 21:36:27
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.12 kb
#include <cstdio>
#include <vector>

using namespace std;

int k,n,m,l[200001],r[200001],lg[200001],v[100001],d[20][400001];

vector <int> g[100001];

void dfs(int nod,int lev)
{
    unsigned int i;
	r[k]=nod;
	++k;
	l[k]=lev;
	v[nod]=k;
	for(i=0;i<g[nod].size();++i)
	{
		dfs(g[nod][i],lev+1);
		r[++k]=nod;
		l[k]=lev;
	}
}

void rmq()
{
    int i,j,c;
	for(i=2;i<=k;++i)
		lg[i]=lg[i>>1]+1;
	for(i=1;i<=k;++i)
		d[0][i]=i;
	for(i=1;(1<<i)<k;++i)
		for(j=1;j<=k-(1<<i);++j)
		{
			c=1<<(i-1);
			d[i][j]=d[i-1][j];
			if(l[d[i-1][j+c]]<l[d[i][j]])
				d[i][j]=d[i-1][j+c];
		}
}

int lca(int x,int y)
{
	int diff,c,sol,sh,a=v[x],b=v[y];
	if(a>b)
        swap(a,b);
	diff=b-a+1;
	c=lg[diff];
	sol=d[c][a];
	sh=diff-(1<<c);
	if(l[sol]>l[d[c][a+sh]])
		sol=d[c][a+sh];
	return r[sol];
}

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