Cod sursa(job #471807)

Utilizator vlad.maneaVlad Manea vlad.manea Data 21 iulie 2010 01:11:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 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> Logs;
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)
{
	int j = Logs[r - l + 1];
	return min(Rmq[j][l], Rmq[j][r - (1 << j) + 1]);
}

int main()
{
	int x, y, i, j, k;

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

	fin >> N >> M;

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

	for (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 (i = 1; i <= N; ++i)
		Rmq[0].push_back(Values[i]);

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

	Logs.push_back(0);
	for (j = 0, i = 1; (1 << j) <= N; ++j)
		for (; i < (1 << (j + 1)) && i <= N; ++i)
			Logs.push_back(j);

	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;
}