Cod sursa(job #471804)

Utilizator vlad.maneaVlad Manea vlad.manea Data 21 iulie 2010 00:50:49
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <fstream>
#include <vector>
#define nmax 131072
#define lmax 32

using namespace std;

int N, M;
vector<int> Children[nmax];
vector<int> Values;
vector<int> Positions;
vector<int> Rmq[lmax];

void path(int n)
{
	if (Positions[n] == 0)
		Positions[n] = Values.size();

	Values.push_back(n);

	for (vector<int>::iterator i = Children[n].begin(); i != Children[n].end(); ++i)
	{
		path(*i);
		Values.push_back(n);
	}
}

int ans(int l, int r)
{
	if (l == r)
		return Rmq[0][l];

	int j;
	for (j = 0; (1 << j) <= r - l + 1; ++j);
	--j;

	if (l + (1 << j) <= r)
		return min(Rmq[j][l], ans(l + (1 << j), r));
	else
		return Rmq[j][l];
}

int main()
{
	int x, y;

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

	fin >> N >> M;

	Positions.push_back(0);
	Positions.push_back(0);

	for (int i = 2; i <= N; ++i)
	{
		fin >> x;
		Children[x].push_back(i);
		Positions.push_back(0);
	}

	Values.push_back(0);
	path(1);

	N = Values.size() - 1;

	Rmq[0].push_back(0);
	for (int i = 1; i <= N; ++i)
		Rmq[0].push_back(Values[i]);

	for (int j = 1; (1 << j) <= N; ++j)
	{
		Rmq[j].push_back(0);
		for (int i = 1; i + (1 << j) - 1 <= N; ++i)
			Rmq[j].push_back(min(Rmq[j - 1][i], Rmq[j - 1][i + (1 << (j - 1))]));
	}

	while (M--)
	{
		fin >> x >> y;
		
		x = Positions[x];
		y = Positions[y];

		fout << ans((x < y? x: y), (x < y? y: x)) << '\n';
	}

	fin.close();
	fout.close();

	return 0;
}