Cod sursa(job #2788075)

Utilizator Langa_bLanga Radu Langa_b Data 24 octombrie 2021 21:10:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <fstream>
#include <vector>
#include <cmath>
#define DIM 210000
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
struct much {
	vector<int>c;
};
vector<much> mu;
int n, m, t[DIM], euler[DIM], lvl[DIM], first[DIM], rmq[DIM << 1][20], d[DIM];
void DFS(int poz, int nivel) {
	euler[0]++;
	euler[euler[0]] = poz;
	if (first[poz] == 0) {
		first[poz] = euler[0];
	}
	lvl[euler[0]] = nivel;
	for (int i = 0; i < mu[poz].c.size(); i++) {
		DFS(mu[poz].c[i], nivel + 1);
		euler[0]++;
		euler[euler[0]] = poz;
		lvl[euler[0]] = nivel;
	}
}
int main() {
	cin >> n >> m;
	for (int i = 0; i <= n; i++) {
		mu.emplace_back(much());
	}
	for (int i = 2; i <= n; i++) {
		cin >> t[i];
		mu[t[i]].c.emplace_back(i);
	}
	DFS(1, 0);
	int cnt = euler[0];
	for (int i = 1; i <= cnt; i++) {
		rmq[i][0] = i;
	}
	for (int j = 1, lg = 2; lg <= cnt; lg *= 2, j++) {
		for (int i = 1; i + lg <= cnt; i++) {
			int st = lvl[rmq[i][j - 1]];
			int dr = lvl[rmq[i + lg / 2][j - 1]];
			if (st < dr) {
				rmq[i][j] = rmq[i][j - 1];
			}
			else {
				rmq[i][j] = rmq[i + lg / 2][j - 1];
			}
		}
	}
	d[1] = 0;
	for (int i = 2; i <= cnt; i++) {
		d[i] = d[i / 2] + 1;
	}
	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		x = first[x];
		y = first[y];
		if (x > y) {
			swap(x, y);
		}
		int l = y - x + 1;
		int st = rmq[x][d[l]];
		int dr = rmq[y - (1 << d[l]) + 1][d[l]];
		int index = min(lvl[dr], lvl[st]);
		if (index == lvl[dr]) {
			cout << euler[dr] << '\n';
		}
		else {
			cout << euler[st] << '\n';
		}
	}
}