Cod sursa(job #2983776)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 22 februarie 2023 22:35:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.37 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 2e5;
const int SMAX = 512;
const int LGMAX = 18;
const int KMAX = 2e5;

int n, k;
vector<int> adj[NMAX + 1];
vector<int> euler;
int dep[NMAX + 1], tin[NMAX + 1];
int rmq[LGMAX + 1][NMAX + 1];

void dfs(int u = 1, int v = 0) {
	dep[u] = dep[v] + 1;
	tin[u] = euler.size();
	euler.emplace_back(u);

	for(const auto &it: adj[u]) if(it != v) {
		dfs(it, u);
		euler.emplace_back(u);
	}
}

int mim(int u, int v) {
	if(dep[u] < dep[v]) {
		return u;
	}
	return v;
}

int query(int le, int ri) {
	int len = ri - le + 1, lg = __lg(len);
	return mim(rmq[lg][le], rmq[lg][ri - (1 << lg) + 1]);
}

int lca(int u, int v) {
	int le = tin[u], ri = tin[v];
	if(le > ri) {
		swap(le, ri);
	}
	return query(le, ri);
}

int main() {
	ios_base :: sync_with_stdio(false);

	fin >> n >> k;

	for(int i = 2; i <= n; i++) {
		int p;
		fin >> p;

		adj[i].emplace_back(p);
		adj[p].emplace_back(i);
	}

	dfs();

	for(int i = 0; i < (int) euler.size(); i++) {
		rmq[0][i] = euler[i];
	}
	for(int i = 1; (1 << i) <= (int) euler.size(); i++) {
		for(int j = 0; j + (1 << i) - 1 < (int) euler.size(); j++) {
			rmq[i][j] = mim(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
		}
	}

	for(int i = 1; i <= k; i++) {
		int u, v;
		fin >> u >> v;

		fout << lca(u, v) << '\n';
	}

	fin.close();
	fout.close();
	return 0;
}