Cod sursa(job #2877508)

Utilizator QwertyDvorakQwerty Dvorak QwertyDvorak Data 24 martie 2022 20:33:46
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include <bits/stdc++.h>
using namespace std;

#define pb push_back

#define dbg(x) cout << #x <<": " << x << "\n";
using ll = long long;

const string fn = "lca";
ifstream fin(fn + ".in");
ofstream fout(fn + ".out");

const int mxn = 100000;

int n, q;
vector<int> g[mxn + 5];
int pozInTour[mxn + 5];
int level[(mxn << 1) + 5];
int eulerTour[(mxn << 1) + 5], szE = 0;


int rmq[20][(mxn << 1) + 5];
int logs[(mxn << 1) + 5];

void dfs(int node, int lvlAc) {
	eulerTour[++szE] = node;
	level[szE] = lvlAc;
	pozInTour[node] = szE;
	for (auto i : g[node]) {
		dfs(i, lvlAc + 1);
		eulerTour[++szE] = node;
		level[szE] = lvlAc;
	}
}

void rmqq() {
// pozitii
	for (int i = 1; i <= szE; ++i)
		rmq[0][i] = i;

	for (int i = 1; (1 << i) <= szE; ++i)
		for (int j = 1; j + (1 << i) - 1 <= szE; ++j) {
			int k = j + (1 << (i - 1));
			if (level[rmq[i - 1][j]] < level[rmq[i - 1][k]])
				rmq[i][j] = rmq[i - 1][j];
			else rmq[i][j] = rmq[i - 1][k];
		}

}

int main() {
	fin >> n >> q;

	for (int i = 2; i <= n; ++i) {
		int x;
		fin >> x;
		g[x].pb(i);

	}

	dfs(1, 0);

	logs[1] = 0;
	for (int i = 2; i <= szE; ++i)
		logs[i] = logs[i / 2] + 1;
	rmqq();

	for (int i = 1; i <= q; ++i) {
		int x, y;
		fin >> x >> y;
		x = pozInTour[x];
		y = pozInTour[y];
		int k = logs[y - x + 1];
		int ans = 0;
		if (level[rmq[k][x]] < level[rmq[k][y - (1 << k) + 1]])
			ans = rmq[k][x];
		else ans = rmq[k][y - (1 << k) + 1];
		fout << eulerTour[ans] << '\n';
	}

	return 0;
}