Cod sursa(job #1784880)

Utilizator ArkinyStoica Alex Arkiny Data 20 octombrie 2016 16:53:23
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;

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

vector<int> G[100010];

int E[300010],C[100010], F[100010],nr;
int RMQ[21][300010],P[300010];
void eulerian_path(int x,int f,int level)
{
	++nr;
	RMQ[0][nr] = x;
	E[nr] = level;
	if (C[x] == 0)
		C[x] = nr;
	F[x] = nr;

	for (int i = 0;i < G[x].size();++i)
	{
		if (G[x][i] != f)
		{
			eulerian_path(G[x][i], x, ++level);
			++nr;
			RMQ[0][nr] = x;
			E[nr] = level;
			if (C[x] == 0)
				C[x] = nr;
			F[x] = nr;
		}
	}

}

void build_RMQ()
{
	for (int i = 1;i <= 20;++i)
		for (int j = 1;j + (1 << i) -1 <= nr;++j)
			if (E[RMQ[i - 1][j]] < E[RMQ[i - 1][j + (1 << (i - 1))]])
				RMQ[i][j] = RMQ[i - 1][j];
			else
				RMQ[i][j] = RMQ[i - 1][j + (1 << (i - 1))];

}

int query_RMQ(int a, int b)
{
	int put = P[b - a+1];
	if (E[RMQ[put][a]] < E[RMQ[put][b - (1 << put) +1]])
		return RMQ[put][a];
	else
		return RMQ[put][b - (1 << put) + 1];
}

int main()
{
	int N,Q;
	in >> N >> Q;

	P[1] = 0;
	for (int i = 2;i <= N;++i)
		P[i] = P[i / 2] + 1;

	for (int i = 2;i <= N;++i)
	{
		int e;
		in >> e;
		G[e].push_back(i);
	}

	eulerian_path(1,0,0);

	build_RMQ();

	for (int i = 1;i <= Q;++i)
	{
		int x, y;
		in >> x >> y;
		if (C[x] < F[y])
			out << query_RMQ(C[x], F[y])<<'\n';
		else if (C[x]>F[y])
			out << query_RMQ(F[y], C[x]) << '\n';
		else
			out << x << '\n';
	}
	

	return 0;
}