Cod sursa(job #717403)

Utilizator rares192Preda Rares Mihai rares192 Data 19 martie 2012 21:46:38
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.18 kb
#include<fstream>
#include<vector>
using namespace std;

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

#define LMAX 200100
int n, m, rmq[20][LMAX];
int euler[LMAX], nivel[LMAX];
vector<int> g[LMAX];
int e=1, nv;

void DFS(int );
void RMQ();
int Query(int, int);

int main()
{
	int a, b;
	fin >> n >> m;
	for( int i = 2; i <= n; ++i)
	{
		fin >> a;
		g[a].push_back(i);
	}
	
	DFS(1);
	RMQ();
	
	for(int i = 1; i <= m; ++i)
	{
		fin >> a >> b;
		fout << Query(a, b) << "\n";
	}		
	
	fin.close();
	fout.close();
	return 0;
}

void DFS(int nod)
{
	int i;
	euler[ ++euler[0] ] = nod;
	nivel[nod] = euler[0];
	for(i = 0; i < (int)g[nod].size(); ++i)
	{
		DFS( g[nod][i] );
		euler[ ++euler[0] ] = nod;
	}
}

void RMQ()
{
	for(int i = 1; i < euler[0]; ++i)
		rmq[0][i] = euler[i];
	
	for(int i = 1; (1 << i) <= euler[0]; ++i)
		for(int j = 1; j + (1 << i) - 1 <= euler[0]; ++j)
			rmq[i][j] = min(rmq[i-1][j], rmq[i-1][j + (1 << (i-1))]);
}

int Query(int a, int b)
{
	int x, y, i;
	x = nivel[a]; 
	y = nivel[b];
	if( x > y) swap(x,y);
	for(i = 1; (1 << i) <= (y-x+1); ++i);
		--i;
	return min(rmq[i][x], rmq[i][y - (1 <<i) + 1]);
}