Cod sursa(job #555527)

Utilizator popoiu.georgeGeorge Popoiu popoiu.george Data 15 martie 2011 16:21:56
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.33 kb
#include<fstream>
#include<vector>
#define inf "lca.in"
#define outf "lca.out"
#define NMax 100100
using namespace std;

fstream f(inf,ios::in),g(outf,ios::out);

int N, M;
int L[2*NMax], E[2*NMax], First[NMax], K, viz[NMax];
int rmq[2*NMax][18], lg[2*NMax];

vector<int> G[NMax];

void DFS(int u, int level)
{
	E[++K] = u; L[K] = level;
	First[u] = K; viz[u] = 1;
	for(int i=0; i<G[u].size(); i++)
	{
		int v = G[u][i];
		if( !viz[v] )
		{
			DFS(v, level+1);
			E[++K] = u; L[K] = level;
		}
	}
}

void RMQ()
{
	for(int i=2; i<=K; i++) lg[i] = lg[i/2] + 1;
	for(int i=1; i<=K; i++) rmq[i][0] = i;
	
	for(int i=1; (1<<i)<=K; i++)
		for(int j=1; j + (1<<i) - 1 <= K ; j++)
		{
			int l = 1<<(i-1);
			rmq[j][i] = rmq[j][i-1];
			if( L[ rmq[ j+l ][i-1] ] < L[ rmq[j][i] ] ) rmq[j][i] = rmq[ j+l ][i-1];
		}
}

inline int min(int a,int b) { return ( a<b ? a : b ); }

inline int lca(int u, int v)
{
	int a = First[u], b = First[v];
	if( a>b ) swap(a,b);
	int l = b-a+1; int k = lg[l];
	int dif = l - (1<<k);
	int sol = rmq[a][k];
	if( L[ rmq[a+dif][k] ] < L[sol] ) sol = rmq[a+dif][k];
	return E[sol];
}

void read()
{
	f>>N>>M; int a, u, v;
	for(int i=2; i<=N; i++)
	{
		f>>a;
		G[i].push_back(a); G[a].push_back(i);
	}
	DFS(1,0);
	RMQ();
	for(int i=1; i<=M; i++)
	{
		f>>u>>v;
		g<< lca(u,v) <<"\n";
	}
}

int main()
{
	read(); 
	f.close(); g.close();
	return 0;
}