Cod sursa(job #479600)

Utilizator razvi9Jurca Razvan razvi9 Data 24 august 2010 15:55:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.48 kb
#include <fstream>
#include <vector>
using namespace std;

int n, m;
vector<vector<int> > a;
vector<pair<int, int> > b;
vector<int> p;

void df(int v, int niv = 0)
{
	p[v] = b.size();
	b.push_back(make_pair(v, niv));
	for(vector<int>::iterator it = a[v].begin(); it != a[v].end(); ++ it)
	{
		df(*it, niv + 1);
		b.push_back(make_pair(v, niv));
	}
}

vector<vector<int> > rmq;
#define nod first
#define nivel second

void buildRMQ()
{
	int n = b.size();
	int x, y;
	rmq.push_back(vector<int>(n));
	for(int i=0;i<n;++i)
		rmq[0][i] = i;
	for(int i=1;(1<<i)<=n;++i)
	{
		rmq.push_back(vector<int>(n));
		for(int j=0;j<n;++j)
		{
			x = j, y = j + (1 << (i - 1));
			if(y >= n) y = n-1;

			x = rmq[i-1][x], y = rmq[i-1][y];

			if(b[x].nivel <= b[y].nivel)
				rmq[i][j] = x;
			else
				rmq[i][j] = y;
		}
	}
}

int queryRMQ(int st, int dr)
{
	if (st > dr)
		swap(st, dr);
	int lg = dr - st + 1, j;
	for(j=-1;lg;++j, lg >>= 1);
	dr = dr - (1 << j) + 1;
	st = rmq[j][st]; dr = rmq[j][dr];
	if(b[st].nivel <= b[dr].nivel)
		return b[st].nod;
	return b[dr].nod;
}

inline int query(int x, int y)
{
	return queryRMQ(p[x], p[y]);
}

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

	int x, y;
	fin >> n >> m;
	a.resize(n + 1);
	p.resize(n + 1);
	for(int i=2;i<=n;++i)
	{
		fin >> x;
		a[x].push_back(i);
	}

	df(1);

	buildRMQ();

	while(m--)
	{
		fin >> x >> y;
		fout << query(x, y) << "\n";
	}

	return 0;
}