Cod sursa(job #1427611)

Utilizator gabi.cristacheGabi Cristache gabi.cristache Data 2 mai 2015 17:23:42
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <fstream>
#include <vector>

#define MaxN 100005
#define MaxLG 20

using namespace std;

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

int N, M, L[2 * MaxN], E[2 * MaxN], firstAppearance[MaxN], k, rmq[MaxN][4 * MaxLG];
int lg[2 * MaxN];

vector<int> G[MaxN];

int min(int a, int b) {
	return a < b ? a : b;
}

void dfs(int node, int level) {
	E[++k] = node;
	L[k] = level;
	firstAppearance[node] = k;

	for (unsigned int i = 0; i < G[node].size(); ++i) {
		dfs(G[node][i], level + 1);
		E[++k] = node;
		L[k] = level;
	}
}

void build_rmq() {
	for (int i = 2; i <= k; ++i)
		lg[i] = lg[i / 2] + 1;

	for (int i = 1; i <= k; ++i)
		rmq[i][0] = i;

	for (int j = 1; (1 << j) <= k; ++j) {
		for (int i = 1; i + (1 << j) - 1 <= k; ++i) {
			int half = 1 << (j - 1);
			int minn = min(L[rmq[i][j - 1]], L[rmq[i + half][j - 1]]);
			rmq[i][j] = minn == L[rmq[i][j - 1]] ? rmq[i][j - 1] : rmq[i + half][j - 1];
		}
	}
}

int lca(int x, int y) {
	int a = firstAppearance[x];
	int b = firstAppearance[y];

	if (a > b) {
		int temp = a;
		a = b;
		b = temp;
	}

	int diff = b - a + 1;
	int lg2 = lg[diff];
	int offset = diff - (1 << lg2);

	if (L[rmq[a][lg2]] < L[rmq[a + offset][lg2]])
		return E[rmq[a][lg2]];
	else
		return E[rmq[a + offset][lg2]];	
}

int main() {
	fin >> N >> M;

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

	dfs(1, 0);

	build_rmq();

	for (int i = 1; i <= M; ++i) {
		int x, y;
		fin >> x >> y;
		fout << lca(x, y) << '\n';
	}

	return 0;
}