Cod sursa(job #2673910)

Utilizator gavra_bogdanBogdan Gavra gavra_bogdan Data 18 noiembrie 2020 09:48:47
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.25 kb
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>

const int nmax = 2e5 + 5;

std::vector<int>v, g[nmax], l;
int rmq[23][nmax], f[nmax];

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

void dfs(int node, int father, int h) {
	v.push_back(node);
	f[node] = v.size() - 1;
	l.push_back(h);
	for(int x:g[node])
		if (x != father) {
			dfs(x, node, h + 1);
			v.push_back(node);
			l.push_back(h);
		}
}

int lca(int a, int b) {
	a = f[a], b = f[b];
	if (a > b) std::swap(a, b);
	int lg = (int)log2(b - a + 1);
	return ((l[rmq[lg][a]] < l[rmq[lg][b - (1 << lg) + 1]]) ? v[rmq[lg][a]] : v[rmq[lg][b - (1 << lg) + 1]]);
}

int main() {
	std::ifstream fin("lca.in");
	std::ofstream fout("lca.out");
	std::ios::sync_with_stdio(false);
	fin.tie(0);
	fout.tie(0);
	int n, m, x, y;
	fin >> n >> m;
	for(int i=2;i<=n;i++){
		fin >> x;
		g[x].push_back(i);
		g[i].push_back(x);
	}
	dfs(1, 0, 0);
	for (int j = 0; (1 << j) <= v.size(); j++)
		for (int i = 0; i <= v.size() - (1 << j); i++)
			if (j == 0) rmq[j][i] = i;
			else rmq[j][i] = ((l[rmq[j - 1][i]] < l[rmq[j - 1][i + (1 << (j-1))]]) ? rmq[j - 1][i] : rmq[j - 1][i + (1 << (j-1))]);
	while (m--) {
		fin >> x >> y;
		fout << lca(x, y) << "\n";
	}
}