Cod sursa(job #615216)

Utilizator moonbeamElma Moonbeam moonbeam Data 8 octombrie 2011 22:10:01
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.33 kb
#include<cstdio>
#include<vector>
using namespace std;
#define pb push_back
#define NM 100005
vector<int> a[NM];
int N,M,x,y;
int dep[NM],pr[NM],e[19][NM<<1],log[NM<<1],rep[NM<<1];
void read()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d%d",&N,&M);
	for (int i=2; i<=N; ++i)
	{
		scanf("%d",&x);
		a[x].pb(i);
	}
}
void df(int nod)
{
	rep[++rep[0]]=nod;
	pr[nod]=rep[0];
	vector<int>::iterator it=a[nod].begin(),end=a[nod].end();
	for (;it!=end; ++it)
	{
		dep[*it]=dep[nod]+1;
		df(*it);
		rep[++rep[0]]=nod;
	}
}
void rmg()
{
	log[0]=log[1]=0;
	e[0][1]=rep[1];
	for (int i=2; i<=rep[0]; ++i)
	{
		log[i]=1+log[i>>1];
		e[0][i]=rep[i];
	}
	for (int i=1; i<=log[rep[0]]; ++i)
	{
		int lung=1<<i;
		int jum=lung>>1;
		for (int j=1; j+lung-1<=rep[0]; ++j)
			if (dep[e[i-1][j]]<dep[e[i-1][j+jum]])
				e[i][j]=e[i-1][j];
			else
				e[i][j]=e[i-1][j+jum];
	}
}
int lca(int x , int y)
{
	if (pr[x]>pr[y])
	{
		int aux=x;
		x=y;
		y=aux;
	}
	int lung=1<<log[pr[y]-pr[x]+1];
	int lo=log[pr[y]-pr[x]+1];
	if (dep[e[lo][pr[x]]]<dep[e[lo][pr[y]-lung+1]])
		return e[lo][pr[x]];
	return e[lo][pr[y]-lung+1];
}
void query()
{
	while (M--)
	{
		scanf("%d%d",&x,&y);
		printf("%d\n",lca(x,y));
	}
}
int main()
{
	read();
	df(1);
	rmg();
	query();
	return 0;
}