Cod sursa(job #1235110)

Utilizator vladrochianVlad Rochian vladrochian Data 28 septembrie 2014 19:45:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.23 kb
#include <fstream>
#include <vector>
using namespace std;
const int NMAX = 100005;

int N, Q, esize,
    euler[2 * NMAX], lg[2 * NMAX], level[NMAX], first[NMAX],
    rmq[20][2 * NMAX];
vector<int> G[NMAX];

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

int MinLevel(int x, int y) {
	return level[x] < level[y] ? x : y;
}

void DFS(int node) {
	euler[++esize] = node;
	first[node] = esize;
	for (int son : G[node]) {
		level[son] = level[node] + 1;
		DFS(son);
		euler[++esize] = node;
	}
}

void BuildRMQ() {
	for (int i = 2; i <= esize; ++i)
		lg[i] = lg[i >> 1] + 1;
	for (int i = 1; i <= esize; ++i)
		rmq[0][i] = euler[i];
	for (int i = 1; (1 << i) <= esize; ++i)
		for (int j = 1; j <= esize - (1 << i) + 1; ++j)
			rmq[i][j] = MinLevel(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
}

int LCA(int x, int y) {
	x = first[x];
	y = first[y];
	if (x > y)
		swap(x, y);
	int exp = lg[y - x];
	return MinLevel(rmq[exp][x], rmq[exp][y - (1 << exp) + 1]);
}

int main() {
	fin >> N >> Q;
	for (int i = 2; i <= N; ++i) {
		int father;
		fin >> father;
		G[father].push_back(i);
	}
	DFS(1);
	BuildRMQ();
	while (Q--) {
		int x, y;
		fin >> x >> y;
		fout << LCA(x, y) << "\n";
	}
	return 0;
}