Cod sursa(job #2939677)

Utilizator average_disappointmentManolache Sebastian average_disappointment Data 13 noiembrie 2022 23:21:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");

const int nmax = 1e5, logmax = 18;
int n, m, euler_index, logs[nmax * 2], pos[nmax + 1], level[nmax * 2] , euler[nmax * 2], rmq[nmax * 2][logmax + 1];
vector<int> edges[nmax + 1];

void dfs(int nod, int curr_level) {

		pos[nod] = ++euler_index;

		euler[euler_index] = nod, level[euler_index] = curr_level;

		for (auto child : edges[nod])
			if (!pos[child]) {

				dfs(child, curr_level + 1);

				euler[++euler_index] = nod, level[euler_index] = curr_level;
			}
}

int query(int x, int y) {

	int len = logs[y - x + 1];

	if (level[rmq[x][len]] <= level[rmq[y - (1 << len) + 1][len]])
		return rmq[x][len];
	return rmq[y - (1 << len) + 1][len];
}

int main() {

	cin >> n >> m;

	logs[0] = -1;
	for (int i = 1; i < nmax * 2; i++)
		logs[i] = logs[i / 2] + 1;

	for (int i = 1; i < n; i++) {

		int t; 
		cin >> t;
		edges[t].push_back(i + 1), edges[i + 1].push_back(t);
	}

	dfs(1, 0);

	for (int i = 1; i < 2 * n; i++)
		rmq[i][0] = i;

	for (int j = 1; (1 << j) < 2 * n; j++) {

		for (int i = 1; i + (1 << j) - 1 < 2 * n; i++) {

			if (level[rmq[i][j - 1]] <= level[rmq[i + (1 << (j - 1))][j - 1]])
				rmq[i][j] = rmq[i][j - 1];
			else
				rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
		}
	}

	for (int i = 1; i <= m; i++) {

		int x, y;
		cin >> x >> y;

		if (pos[x] > pos[y])
			swap(x, y);

		cout << euler[query(pos[x], pos[y])] << "\n";
	}
}