Cod sursa(job #3354048)

Utilizator Alexutu008Ionita Alexandru-Dumitru Alexutu008 Data 14 mai 2026 13:51:27
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.25 kb
#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 1, E = 19;

int n, q, lvl[N], lg[N];
int t[E][N]; // [i, j] -> stramosul lui j la dist 2**j
vector<int> mc[N];

void dfs(int nod) {
	for (auto& i : mc[nod]) {
		lvl[i] = lvl[nod] + 1;
		dfs(i);
	}
}

int anc(int nod, int ord) {
	for (int bit = 1; bit <= ord; bit <<= 1) {
		if (bit & ord) {
			nod = t[bit-1][nod];
		}
	}

	return nod;
}

int lca(int x, int y) {
	int e = lg[lvl[x]];

	while (e >= 0) {
		if (t[e][x] != t[e][y]) {
			x = t[e][x];
			y = t[e][y];
		}
		--e;
	}

	return t[0][x];
}

int main() {
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> n >> q;
	for (int i = 2; i <= n; ++i) {
		int x; cin >> x;

		mc[x].push_back(i);
		t[0][i] = x;
	}

	dfs(1);

	for (int i = 2; i < N; ++i) lg[i] = lg[i / 2] + 1;

	for (int e = 1; e < E; ++e) {
		for (int nod = 1; nod <= n; ++nod) {
			t[e][nod] = t[e - 1][t[e - 1][nod]];
		}
	}

	while (q--) {
		int x, y; cin >> x >> y;

		if (lvl[x] > lvl[y]) swap(x, y);

		y = anc(y, lvl[y] - lvl[x]);

		if (x == y) {
			cout << x << '\n';
		}
		else {
			cout << lca(x, y) << '\n';
		}
	}

	return 0;
}