Cod sursa(job #2352043)

Utilizator flibiaVisanu Cristian flibia Data 22 februarie 2019 21:54:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.08 kb
#include <bits/stdc++.h>

using namespace std;

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

int n, m, x, y, viz[100100], st[200100], niv[100100], pos[100100], vf, rmq[20][200100];
vector <int> v[100100];

void dfs(int x, int lvl) {
	viz[x] = 1;
	niv[x] = lvl;
	st[++vf] = x;
	pos[x] = vf;
	for (auto y : v[x]) 
		if (!viz[y]) {
			dfs(y, lvl + 1);
			st[++vf] = x;
		}
}

void build() {
	for (int i = 1; i <= vf; i++)
		rmq[0][i] = st[i];
	int sz = log2(vf);
	for (int i = 1; i <= sz; i++)
		for (int j = 1; j <= vf; j++)
			rmq[i][j] = (niv[rmq[i - 1][j]] < niv[rmq[i - 1][j + (1 << (i - 1))]] ? rmq[i - 1][j] : rmq[i - 1][j + (1 << (i - 1))]);
}

void solve(int x, int y) {
	x = pos[x];
	y = pos[y];
	if (x > y)
		swap(x, y);
	int sz = log2(y - x + 1);
	out << (niv[rmq[sz][x]] < niv[rmq[sz][y - (1 << sz) + 1]] ? rmq[sz][x] : rmq[sz][y - (1 << sz) + 1]) << '\n';
}

int main() {
	in >> n >> m;
	for (int i = 2; i <= n; i++) {
		in >> x;
		v[x].push_back(i);
	}
	dfs(1, 1);
	build();
	while (m--) {
		in >> x >> y;
		solve(x, y);
	}
	return 0;
}