Cod sursa(job #434015)

Utilizator cosmin79Carabet Cosmin Andrei cosmin79 Data 4 aprilie 2010 21:54:43
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 kb
#include <fstream>
#include <vector>
#define NMAX 100005
#define LMAX 200005
#define LG 19
#define pb push_back
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n,m,euler[LMAX],r,grd[NMAX],ap[NMAX],lg[LMAX],rmq[LG][LMAX],a,b;
char viz[NMAX];
vector <int> A[NMAX];
void read()
{
	in>>n>>m;
	int i,x;
	for (i=1; i<n; i++)
	{
		in>>x;
		A[x].pb(i+1);
	}
}
void dfs(int nod)
{
	viz[nod]=1;
	int i,vec;
	for (i=0; i<A[nod].size(); i++)
	{
		vec=A[nod][i];
		if (!viz[vec])
		{
			euler[++r]=vec;
			grd[vec]=grd[nod]+1;
			if (!ap[vec])
				ap[vec]=r;
			dfs(vec);
			euler[++r]=nod;
		}
	}
}
inline int min(int x,int y)
{
	return grd[x]<grd[y] ? x : y;
}
void prepare()
{
	int i,j,t,k;
	for (i=1; i<=r; i++)
	{
		lg[i]=i>=2 ? lg[i/2]+1 : 0;
		rmq[0][i]=euler[i];
	}
	for (i=1; (1<<i)<=r; i++)
	{
		t=1<<i; k=1<<(i-1);
		for (j=1; j<=r-t+1; j++)
			rmq[i][j]=min(rmq[i-1][j],rmq[i-1][(j+t-1)-k+1]);
	}
}
int main()
{
	read();
	euler[++r]=1;
	dfs(1);
	prepare();
	int t,l,p;
	while (m--)
	{
		in>>a>>b;
		a=ap[a]; b=ap[b];
		if (a>b)
			t=a,a=b,b=t;
		l=lg[b-a+1]; p=1<<l;
		out<<min(rmq[l][a],rmq[l][b-p+1])<<'\n';
	}	
	return 0;
}