Cod sursa(job #371290)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 4 decembrie 2009 19:06:19
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.19 kb
#include<fstream>
#include<iostream>
#include<vector>
#define ND 1<<17
#define LE 1<<18
using namespace std;
vector<int> v[ND];
int n,i,t,m,nr,poz[ND],niv[ND],gr[ND],dad[ND],
rmq[18][LE],lin[LE],pov[LE];
void read(),solve(),PE(int nod),RMQ();
int main()
{
	read();
	solve();
	return 0;
}
void read()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	cin>>n>>m;
	for(i=2;i<=n;i++)
	{
		cin>>t;dad[i]=t;
		v[t].push_back(i);
	}
}
void solve()
{
	int U,V,a,b,L,P;
	PE(1);
	for(i=2;i<=nr;i<<=1)lin[i]=1;
	for(i=1;i<=nr;i++){lin[i]+=lin[i-1];pov[i]=1<<lin[i];}
	RMQ();
	for(;m;m--)
	{
		cin>>a>>b;//scanf("%d%d",&a,&b);
		a=poz[a];b=poz[b];
		if(a>b)a^=b^=a^=b;
		L=lin[b-a+1];P=pov[b-a+1];
		U=rmq[L][a];V=rmq[L][b-P+1];
		U=niv[U]<niv[V]?U:V;
		printf("%d\n",U);
	}
}
void PE(int nod)
{
	vector<int>::iterator it;
	niv[nod]=niv[dad[nod]]+1;
	rmq[0][++nr]=nod;poz[nod]=nr;
	for(it=v[nod].begin();it!=v[nod].end();it++)
	{
		PE(*it);rmq[0][++nr]=nod;
	}
	
}
void RMQ()
{
	int S,D,L,LL,K=0,k=-1;
	for(L=1,LL=2;LL<=nr;L<<=1,LL<<=1)
	{
		k++;K++;
		for(S=1,D=LL;D<=nr;S++,D++)
			rmq[K][S]=niv[rmq[k][S+L]]>niv[rmq[k][S]]?rmq[k][S]:rmq[k][S+L];
	}
}