Cod sursa(job #3218105)

Utilizator vladdobro07vladdd vladdobro07 Data 26 martie 2024 00:51:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.45 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax = 1e5, inf = 79797979;

vector<vector<int>> rmq(19, vector<int>(2 * nmax + 1, inf));
vector<int> lvl(nmax + 1), edge[nmax + 1], prim(nmax + 1), lg(2 * nmax + 1);
vector<bool> viz(nmax + 1);

int n, m, x, y, len = 0, rez = 0;

void dfs(int node, int level = 0) {
	viz[node] = 1;
	lvl[node] = level;
	len++;
	rmq[0][len] = node;
	prim[node] = len;
	for(auto fiu : edge[node]) {
		if(viz[fiu] == 0) {
			dfs(fiu, level + 1);
			len++;
			rmq[0][len] = node;
		}
	}
}

void build_log() {
	for(int i = 2; i <= 2 * nmax; i++)
		lg[i] = lg[i / 2] + 1;
}

int r(int node1, int node2) {
	if(lvl[node1] < lvl[node2])
		return node1;
	return node2;
}

void build_rmq() {
	for(int i = 1; i <= 18; i++) {
		for(int j = 1; j <= len - (1 << i) + 1; j++) {
			rmq[i][j] = r(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
		}
	}
}

int lca(int x, int y) {
	int a = prim[x], b = prim[y], dif, lgdif;
	if(a > b)
		swap(a, b);
	dif = (b - a + 1);
	lgdif = lg[dif];
	return r(rmq[lgdif][a], rmq[lgdif][b - (1 << lgdif) + 1]);
}

void read() {
	fin >> n >> m;
	for(int i = 2; i <= n; i++) {
		fin >> x;
		edge[x].push_back(i);
		edge[i].push_back(x);
	}
	dfs(1);
	build_rmq();
	for(int i = 1; i <= m; i++) {
		fin >> x >> y;
		fout << lca(x, y) << "\n";
	}
}

int main() {
	build_log();
	read();
	return 0;
}