Cod sursa(job #2200983)

Utilizator emiemiEmi Necula emiemi Data 3 mai 2018 00:21:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <fstream>
#include <vector>

using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

int log2(int a) {
	int x = 1, l = 0;
	while (x <= a) {
		x <<= 1;
		++l;
	}
	return (l - 1);
}

int n, N, e;
int *L, *H, **a;
vector<int> v[100001];

void euler(int x, int l) {
	++e;
	a[e][0] = x;
	L[x] = l;
	H[x] = e;

	int length = v[x].size();
	for (int i = 0; i < length; ++i) {
		euler(v[x][i], l + 1);
		++e;
		a[e][0] = x;
	}
}

int minim(int a, int b) {
	return ((L[a] <= L[b]) ? a : b);
}

int main() {
	int m, i, j, k, t;

	f >> n >> m;

	for (i = 2; i <= n; ++i) {
		f >> t;
		v[t].push_back(i);
	}

	N = 2 * n - 1;
	int put2, lim, len = log2(N) + 1;

	L = (int *)malloc((n + 1) * sizeof(int));
	H = (int *)malloc((n + 1) * sizeof(int));
	a = (int **)malloc((N + 1) * sizeof(int *));
	for (i = 1; i <= N; ++i)
		a[i] = (int *)malloc(len * sizeof(int));

	e = 0;
	euler(1, 0);

	for (k = 1; k < len; ++k) {
		put2 = 1 << k;
		lim = N + 1 - put2;
		put2 >>= 1;
		for (i = 1; i <= lim; ++i)
			a[i][k] = minim(a[i][k - 1], a[i + put2][k - 1]);
	}

	int x, y, aux;
	for (i = 1; i <= m; ++i) {
		f >> x >> y;
		if (H[y] < H[x]) {
			aux = x;
			x = y;
			y = aux;
		}
		x = H[x];
		y = H[y];
		lim = y - x + 1;
		put2 = log2(lim);

		g << minim(a[x][put2], a[x + lim - (1 << put2)][put2]) << '\n';
	}
	
	return 0;
}