Cod sursa(job #387358)

Utilizator Alexa_ioana_14Antoche Ioana Alexandra Alexa_ioana_14 Data 27 ianuarie 2010 14:18:21
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.29 kb
#include<vector>
#include<cstdio>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
int k,n,m;
int l[N<<1],h[N<<1],f[N];
int a[N<<4],st,dr,sol,hsol;
vector <int> g[N];
int x,y;
void citire()
{
	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);
		g[x].push_back(i);
	}
}
void dfs(int nod,int lev)
{
	h[++k]=nod; 
	l[k]=lev; 
	f[nod]=k; 
	size_t g1=g[nod].size();
	for (size_t i=0; i<g1;++i)
	{
		dfs(g[nod][i],lev+1);
		h[++k]=nod;
		l[k]=lev;
	}
}
void build(int nod,int li,int lf)
{
	if(li==lf)
	{
		a[nod]=li;
		return;
	}
	int mij=(li+lf)>>1;
	build(nod<<1,li,mij);
	build((nod<<1)+1,mij+1,lf);
	if(l[a[nod<<1]]<=l[a[(nod<<1)+1]])
		a[nod]=a[nod<<1];
	else
		a[nod]=a[(nod<<1)+1];
}
void query(int nod,int li,int lf)
{
	if(st<=li&&lf<=dr)
	{
		if(l[a[nod]]<hsol)
		{
			sol=h[a[nod]];
			hsol=l[a[nod]];
		}
		return;
	}
	int mij=(li+lf)>>1;
	if(st<=mij) query(nod<<1,li,mij);
	if(mij<dr) query((nod<<1)+1,mij+1,lf);
}
int lca(int x, int y)
{
	st=f[x],dr=f[y];
	if(st>dr) swap(st,dr);
	sol=hsol=INF;
	query(1,1,k);
	return sol;
}
int main()
{
	citire();
	dfs(1,0);
	build(1,1,k);
	while(m--)
	{
		scanf("%d%d",&x,&y);
		printf("%d\n",lca(x,y));
	}
}