Cod sursa(job #1784914)

Utilizator ArkinyStoica Alex Arkiny Data 20 octombrie 2016 17:46:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;

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

vector<int> G[100010];

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

	for (int i = 0;i < G[x].size();++i)
	{
		
		eulerian_path(G[x][i], level+1);
		T[++nr] = x;
		E[nr] = level;
	}

}

void build_RMQ()
{
	for (int i = 1;i <= 22;++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;

	for (int i = 2;i <= 300000;++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,1);

	for (int i = 1;i <= nr;++i)
		RMQ[0][i] = i;

	build_RMQ();

	for (int i = 1;i <= Q;++i)
	{
		int x, y;
		in >> x >> y;

		if (C[x] < C[y])
			out << T[query_RMQ(C[x], C[y])]<<'\n';
		else if (C[x]>C[y])
			out << T[query_RMQ(C[y], C[x])] << '\n';
		else
			out << x << '\n';
	}
	

	return 0;
}