Cod sursa(job #410014)

Utilizator GheorgheMihaiMihai Gheorghe GheorgheMihai Data 3 martie 2010 23:56:16
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.12 kb
#include<stdio.h>
#include<vector>
using namespace std;
int n,m,nr,log[100002],f[100002],e[100002],l[100002],rmq[20][100002];
vector<int> v[100002];

void dfs(int nod, int niv)
{
	e[++nr]=nod;
	l[nr]=niv;
	f[nod]=nr;
	int i,lim=v[nod].size();
	for(i=0;i<lim;i++)
	{
		dfs(v[nod][i],niv+1);
		e[++nr]=nod;
		l[nr]=niv;
	}
}

void make_rmq()
{
	int i,j,lim;
	for(i=1;i<=nr;i++)
		rmq[0][i]=i;
	for(i=1;(1<<i)<nr;i++)
	{
		lim=nr-(1<<i)+1;
		for(j=1;j<=lim;j++)
		{
			rmq[i][j]=rmq[i-1][j];
			if(l[rmq[i-1][j+(1<<i-1)]]<l[rmq[i][j]])
				rmq[i][j]=rmq[i-1][j+(1<<i-1)];
		}
	}
}

int main()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d%d",&n,&m);
	int i,x,y,sol;
	for(i=2;i<=n;i++)
	{
		scanf("%d",&x);
		v[x].push_back(i);
	}
	dfs(1,0);
	make_rmq();
	for(i=2;i<=nr;i++)
		log[i]=log[i>>1]+1;
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		x=f[x];
		y=f[y];
		if(x>y)
			x^=y^=x^=y;
		sol=rmq[log[y-x+1]][x];
		if(l[sol]>l[rmq[log[y-x+1]][y-(1<<log[y-x+1])+1]])
			sol=rmq[log[y-x+1]][y-(1<<log[y-x+1])+1];
		printf("%d\n",e[sol]);
	}
	return 0;
}