Cod sursa(job #796183)

Utilizator radustn92Radu Stancu radustn92 Data 10 octombrie 2012 20:03:25
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 kb
#include <stdio.h>
#include <vector>
#define NMAX 100005
#define LMAX 200005
#define HMAX 19
#define pb push_back
using namespace std;
int n,m,euler[LMAX],r,C[NMAX];
int B[HMAX][LMAX],lg[LMAX],lvl[NMAX];
vector <int> A[NMAX];
void read()
{
	scanf("%d%d",&n,&m);
	int i,x;
	for (i=2; i<=n; i++)
	{
		scanf("%d",&x);
		A[x].pb(i);
	}
}
void dfs(int nod)
{
	euler[++r]=nod; 
	C[nod]=r;
	int i,vec;
	for (i=0; i<A[nod].size(); i++)
	{
		vec=A[nod][i]; lvl[vec]=lvl[nod]+1;
		dfs(vec);
		euler[++r]=nod;
	}
}
inline int min(int x,int y)
{
	if (lvl[x]<lvl[y])
		return x;
	return y;
}
void prepare()
{
	int i,j,l;
	for (i=1; i<=r; i++)
	{
		B[0][i]=euler[i];
		lg[i]=(i>=2) ? lg[i/2]+1 : 0;
	}
	
	for (i=1; (1<<i)<=r; i++)
	{
		l=1<<(i-1);
		for (j=1; j<=r-(1<<i)+1; j++)
			B[i][j]=min(B[i-1][j],B[i-1][j+l]);
	}
}
void solve()
{
	dfs(1);
	
	prepare();
	
	int i,x,y,aux,l,val;
	for (i=1; i<=m; i++)
	{
		scanf("%d%d",&x,&y);
		x=C[x]; y=C[y];
		if (x>y)
			aux=x,x=y,y=aux;
		l=lg[y-x+1];  val=1<<l;
		printf("%d\n",min(B[l][x],B[l][y-val+1]));
	}
}
int main()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	read();
	solve();
	return 0;
}