Cod sursa(job #555529)

Utilizator popoiu.georgeGeorge Popoiu popoiu.george Data 15 martie 2011 16:24:58
Problema Lowest Common Ancestor Scor 100
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[18][2*NMax], 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[0][i] = 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[i][j] = rmq[i-1][j];
			if( L[ rmq[ i-1 ][j+l] ] < L[ rmq[i][j] ] ) rmq[i][j] = rmq[ i-1 ][j+l];
		}
}

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[k][a];
	if( L[ rmq[k][a+dif] ] < L[sol] ) sol = rmq[k][a+dif];
	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;
}