Cod sursa(job #739352)

Utilizator teodora.petrisorPetrisor Teodora teodora.petrisor Data 22 aprilie 2012 19:54:59
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 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 = i; j<=euler[0] - (1<<i) + 1; ++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]);
}