Cod sursa(job #1921630)

Utilizator dorin31Geman Dorin Andrei dorin31 Data 10 martie 2017 13:33:56
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.24 kb
#include <iostream>
#include <fstream>
#include <vector>

#define maxN 100100

using namespace std;

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

vector<int> v[maxN];
int first[maxN], RMQ[20][2 * maxN], deep[maxN], nr_rmq;

void DFS(int nod)
{
 	RMQ[0][++nr_rmq] = nod;
	first[nod] = nr_rmq;
	for (auto it:v[nod])
    {
 		deep[it] = deep[nod] + 1;
		DFS(it);
		RMQ[0][++nr_rmq] = nod;
	}
}


int LCA(int a, int b)
{
	a = first[a];
	b = first[b];
	if (a > b)
		swap(a, b);
	if (a == b)
		return a;
	int d = 0;
	while ((1 << d) < (b - a + 1))
		++d;
	--d;
	if (deep[RMQ[d][a]] < deep[RMQ[d][b - (1 << d) + 1]])
		return RMQ[d][a];
	return RMQ[d][b - (1 << d) + 1];
}


void make_RMQ()
{
	for (int l = 1; (1 << l) <= nr_rmq; ++l)
		for (int st = 1; st + (1 << l) <= nr_rmq; ++st) {
			int dr = st + (1 << (l - 1));
			if (deep[RMQ[l - 1][st]] < deep[RMQ[l - 1][dr]])
				RMQ[l][st] = RMQ[l - 1][st];
			else
				RMQ[l][st] = RMQ[l - 1][dr];
		}

}


int main() {
 	int n, m;
	fin >> n >> m;
	for (int i = 2; i <= n; ++i)
    {
		int f;
		fin >> f;
		v[f].push_back(i);
	}
 	DFS(1);
	make_RMQ();
	while (m--) {
		int a, b;
		fin >> a >> b;
		fout << LCA(a, b) << '\n';
	}
	return 0;
}