Cod sursa(job #2859763)

Utilizator alextmAlexandru Toma alextm Data 1 martie 2022 21:06:31
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.14 kb
#include <bits/stdc++.h>
using namespace std;

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

const int MAXN = 1e5 + 5;
const int MAXLOG = 20;

int n, nr, rmq[MAXN * 2][MAXLOG], lg[MAXN];
int Euler[MAXN * 2], depth[MAXN], pos[MAXN];
vector<int> G[MAXN];

int minDepth(int a, int b) {
	if(depth[a] < depth[b])
		return a;
	return b;
}

inline void dfs(int node, int lvl = 0) {
	Euler[++nr] = node;
	pos[node] = nr;
	depth[node] = lvl;
	for(auto son : G[node]) {
		dfs(son, lvl + 1);
		Euler[++nr] = node;
	}
}

void buildRMQ() {
	for(int i = 1; i <= nr; i++) {
		rmq[i][0] = Euler[i];
		if(i > 1)
			lg[i] = lg[i / 2] + 1;
	}
	
	for(int k = 1; (1 << k) <= nr; k++)
		for(int i = 1; i + (1 << k) - 1 <= nr; i++)
			rmq[i][k] = minDepth(rmq[i][k - 1], rmq[i + (1 << (k - 1))][k - 1]);
}

int lca(int x, int y) {
	x = pos[x], y = pos[y];
	if(x > y)
		swap(x, y);
		
	int k = lg[y - x + 1];
	return minDepth(rmq[x][k], rmq[y - (1 << k) + 1][k]);
}

int main() {
	int m, x, y;
	fin >> n >> m;
	
	for(int i = 2; i <= n; i++) {
		fin >> x;
		G[x].push_back(i);
	}
	
	dfs(1);
	buildRMQ();
	
	while(m--) {
		fin >> x >> y;
		fout << lca(x, y) << '\n';
	}
	
	return 0;
}