Cod sursa(job #712780)

Utilizator ms-ninjacristescu liviu ms-ninja Data 13 martie 2012 19:47:36
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.22 kb
#include <fstream>
#include <vector>
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");
#define dim 200005
#define pb push_back
#define log 20
vector <int> v[dim];
int rmq[log][dim], n ,m,euler[dim],p,lung[dim],fiu[dim],lg[dim];

void read()
{
	int i, x;
	fin>> n >>m;
	for(i=2;i<=n;++i)
	{
		fin>>x;
		v[x].pb(i);
	}
}

void dfs(int nod, int lev)
{
	int i;
	
	euler[++p]=nod;
	lung[p]=lev;
	fiu[nod]=p;
	for(i=0;i<v[nod].size();++i)
	{
		dfs(v[nod][i],lev+1);
		euler[++p]=nod;
		lung[p]=lev;
	}
}

void build_rmq()
{
	int i, j;
	for(i=2;i<=p;++i)
		lg[i]=lg[i/2]+1;
	for(i=1;i<=p;++i)
		rmq[0][i]=i;
	
	for(i=1;(1<<i)<p;++i)
		for(j=1;j+(1<<i)<=p;++j)
			if(lung[ rmq[i-1][j] ]<lung[ rmq[i-1][j+(1<<(i-1))]] )
				rmq[i][j]=rmq[i-1][j];
			else
				rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
}

void solve()
{
	int  x, y, val;
	for(;m;--m)
	{
		fin>>x >>y;
		x=fiu[x];
		y=fiu[y];
		if(x>y)
			swap(x,y);
		val=lg[y-x+1];
		
		if(lung[ rmq[val][x] ] < lung[ rmq[val][y-(1<<val)+1] ])
			fout<<euler[ rmq[val][x]]<<'\n';
		else
			fout<<euler[ rmq[val][y-(1<<val)+1] ] <<'\n';
	}
}

int main()
{
	read();
	dfs(1,0);
	build_rmq();
	solve();
	
	return 0;
}