Cod sursa(job #1613543)

Utilizator ArkinyStoica Alex Arkiny Data 25 februarie 2016 14:29:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.24 kb
#include<fstream>
#include<algorithm>
#include<vector>
using namespace std;

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

int N, M;

vector<int> G[200010];

int RMQ[22][400100],l,L[400100],E[400100],F[200100];

void DFS(int x,int lev)
{
	L[++l] = lev;
	E[l] = x;
	if(F[x] == 0)
		F[x] = l;
	for (int i = 0; i < G[x].size(); ++i)
	{
		DFS(G[x][i], lev + 1);
		L[++l] = lev;
		E[l] = x;
	}
}

int main()
{
	in >> N >> M;
	for (int i = 2; i <= N; ++i)
	{
		int x;
		in >> x;
		G[x].push_back(i);
	}
	DFS(1, 1);
	for (int i = 1; i <= l; ++i)
		RMQ[0][i]=i;


	for (int p = 1; p <= 22; p++)
	{
		int pw2 = (1 << p);
		for (int j = 1; j + pw2 - 1 <= l; ++j)
		{
			if (L[RMQ[p - 1][j]] < L[RMQ[p - 1][j + pw2 - (pw2 >> 1)]])
				RMQ[p][j] = RMQ[p - 1][j];
			else
				RMQ[p][j] = RMQ[p - 1][j + pw2 - (pw2 >> 1)];
		}
	}

	for (int i = 1; i <= M; ++i)
	{
		int a, b;
		in >> a >> b;
		if (F[b] < F[a])
			swap(a, b);
		a = F[a];
		b = F[b];
		int dif = b - a + 1;
		int put = 0,pw2;
		while ((1 << put) <= dif)
			++put;
		--put;
		pw2 = (1 << put);
		if (L[RMQ[put][a]] < L[RMQ[put][b-pw2+1]])
			out << E[RMQ[put][a]]<<'\n';
		else
			out << E[RMQ[put][b-pw2+1]]<<'\n';
	}



	return 0;
}