Cod sursa(job #2581258)

Utilizator radustn92Radu Stancu radustn92 Data 14 martie 2020 19:43:13
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.45 kb
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

const int NMAX = 100505;
int N, queries, parent[NMAX];
vector<int> G[NMAX];
int heavyChild[NMAX], depth[NMAX], head[NMAX];

int dfs(int node) {
	int currSize = 1, largestChildSize = 0;
	for (auto child : G[node]) {
		depth[child] = depth[node] + 1;
		int childSize = dfs(child);
		currSize += childSize;
		if (childSize > largestChildSize) {
			largestChildSize = childSize;
			heavyChild[node] = child;
		}
	}
	return currSize;
}

void createPaths(int node, int startingNode) {
	head[node] = node;
	if (heavyChild[node] != -1) {
		createPaths(heavyChild[node], startingNode);
	}
	for (auto child : G[node]) {
		if (child != heavyChild[node]) {
			createPaths(child, child);
		}
	}
}

int getLca(int x, int y) {
	while (head[x] != head[y]) {
		if (depth[head[x]] < depth[head[y]]) {
			swap(x, y);
		}
		x = parent[head[x]];
	}

	return depth[x] < depth[y] ? x : y;
}

int main() {
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);

	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	cin >> N >> queries;
	int currParent;
	for (int node = 2; node <= N; node++) {
		scanf("%d", &currParent);
		G[currParent].push_back(node);
		parent[node] = currParent;
	}

	fill(heavyChild, heavyChild + N + 1, -1);
	dfs(1);
	createPaths(1, 1);

	int x, y;
	for (int queryNo = 0; queryNo < queries; queryNo++) {
		scanf("%d%d", &x, &y);
		printf("%d\n", getLca(x, y));
	}
	return 0;
}