Cod sursa(job #388779)

Utilizator AndreyPAndrei Poenaru AndreyP Data 30 ianuarie 2010 22:17:01
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.25 kb
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
#define N 100010
#define pb push_back
int n,m;
int lo[3*N];
int poz[N];
int niv[N];
int a[19][3*N];
vector<int> b[N];
int indice;
inline void citire()
{
	scanf("%d%d",&n,&m);
	int x;
        for(int i=2; i<=n; ++i)
	{
		scanf("%d",&x);
                b[x].pb(i);
	}
}
void dfs(int nod,int h)
{
	poz[nod]=++indice;
	a[0][indice]=nod;
	niv[nod]=h;
	for(size_t i=0,lim=b[nod].size(); i<lim; ++i)
	{
		dfs(b[nod][i],h+1);
		++indice;
		a[0][indice]=nod;
	}
}
inline int minim(int &x,int &y)
{
	if(niv[x]<niv[y])
		return x;
	return y;
}
inline void rmq()
{
	lo[2]=1;
	for(int i=3; i<=indice; ++i)
		lo[i]=lo[i>>1]+1;
	int dim,dim1;
        for(int i=1; i<=lo[indice]; ++i)
	{
		dim=1<<i;
		dim1=dim>>1;
                for(int j=1; j+dim-1<=indice; ++j)
			a[i][j]=minim(a[i-1][j],a[i-1][j+dim1]);
	}
}
int main()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
        citire();
        dfs(1,0);
	rmq();
        int x,y,cat;
	for(int i=0; i<m; ++i)
	{
		scanf("%d%d",&x,&y);
		if(x==y)
		{
			printf("%d\n",x);
			continue;
		}
		if(poz[x]>poz[y])
			swap(x,y);
                cat=lo[poz[y]-poz[x]];
		printf("%d\n",minim(a[cat][poz[x]],a[cat][poz[y]-(1<<cat)+1]));
	}
	return 0;
}