Cod sursa(job #866063)

Utilizator raulstoinStoin Raul raulstoin Data 27 ianuarie 2013 15:04:44
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.32 kb
#include<cstdio>
#include<vector>
#define nmax 100005
using namespace std;
int n,m,a[2*nmax],rmq[18][nmax],l,ind[nmax],nivel[nmax],power[20],level[nmax];
bool use[nmax];
vector<int> G[nmax];
void DFS(int nod,int niv)
{
	vector<int> :: iterator it;
	a[++l]=nod;
	level[l]=niv;
	ind[nod]=l;
	for(it=G[nod].begin();it!=G[nod].end();it++)
	{
		DFS(*it,niv+1);
		a[++l]=nod;
		level[l]=niv;
	}
}
void rmq_build()
{
	int i,j,k;
	for(i=2;i<=l;i++)
        power[i]=power[i/2]+1;
	for(i=1;i<=l;i++)
		rmq[0][i]=i;
	for(i=1;(1<<i)<=l;i++)
		for(j=1;j<=l-(1<<i)+1;j++)
		{
			k=1<<(i-1);
            if(level[rmq[i-1][j + k]]<level[rmq[i-1][j]])
                rmq[i][j]=rmq[i-1][j + k];
			else
				rmq[i][j]=rmq[i-1][j];
		}
}
void solve()
{
	int x,y,dif,i,plus,sol;
	while(m--)
    {
        scanf("%d %d",&x,&y);
		x=ind[x];
		y=ind[y];
		if(x>y)
			swap(x,y);
        dif=y-x+1;
        i=power[dif];
		sol=rmq[i][x];
        plus=dif-(1<<i);
		if(level[rmq[i][x]]>level[rmq[i][x+plus]])
			sol=level[rmq[i][x+plus]];
        printf("%d\n",a[sol]);
    }
}
int main()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d %d",&n,&m);
	int x;
	for(int i=2;i<=n;i++)
	{
		scanf("%d",&x);
		G[x].push_back(i);
	}
	DFS(1,0);
	rmq_build();
	solve();
	return 0;
}