Cod sursa(job #717479)

Utilizator rares192Preda Rares Mihai rares192 Data 19 martie 2012 22:27:43
Problema Lowest Common Ancestor Scor 20
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 LMAX 200100
int n, m, rmq[20][LMAX];
int euler[LMAX], nivel[LMAX];
vector<int> g[LMAX];
int lg[LMAX];

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

int main()
{
	int a, b;
	fin >> n >> m;
	lg[1] = 0;
	for( int i = 2; i <= n; ++i)
	{
		fin >> a;
		g[a].push_back(i);
		lg[i] = lg[i/2] + 1;
	}
	
	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 <= 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 l ,x, y;
	x = nivel[a]; y = nivel[b];
	if( x > y) swap(x,y);
	
	int diff = y-x+1;
	l = lg[diff];
    int sh = diff - (1 << l);
	
	return min(rmq[l][x], rmq[l][x + sh]);
}