Cod sursa(job #661345)

Utilizator ELHoriaHoria Cretescu ELHoria Data 14 ianuarie 2012 12:46:02
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <fstream>
#include <vector>

using namespace std;

typedef vector<int> VI;
typedef VI::const_iterator CIT;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int NMAX = 100005 , MAXL = 20;
VI G[NMAX];
int N , Q , K , x , y;
int rmq[MAXL][NMAX] , H[NMAX<<1] , Lev[NMAX<<1] , First[NMAX<<1] , Lg[NMAX<<1];

void read_data()
{
	fin>>N>>Q;
	for(int i = 2;i <= N;++i)
	{
		fin>>x;
		G[x].push_back(i);
	}
}

void df(int node,int lev)
{
	H[++K] = node;
	Lev[K] = lev;
	First[node] = K;
	for(CIT w = G[node].begin();w != G[node].end();++w)
	{
		df(*w,lev + 1);
		H[++K] = node;
		Lev[K] = lev;
	}
}

void RMQ()
{
	rmq[0][1] = 1;
	for(int i = 2;i <= K;++i)
		Lg[i] = Lg[i>>1] + 1 , rmq[0][i] = i;

	for(int i = 1;(1<<i) < K;++i)
		for(int j = 1;j <= K - (1<<i) + 1;++j)
			rmq[i][j] = Lev[rmq[i-1][j]] < Lev[rmq[i-1][j + (1<<(i-1))]] ? rmq[i-1][j] : rmq[i-1][j + (1<<(i-1))];
}

int lca(int x,int y)
{
	if(First[x] < First[y]) x = First[x] , y = First[y]; else x = First[y] , y = First[x];
	int dif = y - x + 1 ;
	int l = Lg[dif] , sh = dif - (1<<Lg[dif]);
	return Lev[ rmq[l][x] ] < Lev[ rmq[l][x + sh] ] ?  H[ rmq[l][x] ] : H[ rmq[l][x + sh] ];
}

int main()
{
	read_data();
	df(1,0);
	RMQ();
	for(;Q;Q--) 
	{
		fin>>x>>y;
		fout<<lca(x,y)<<'\n';
	}
	return 0;
}