Cod sursa(job #1959659)

Utilizator preda.andreiPreda Andrei preda.andrei Data 9 aprilie 2017 19:25:13
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <fstream>
#include <vector>

using namespace std;

struct Node
{
	int exit_time = 0;
	vector<int> sons;
	vector<int> ancestors;
};

using Tree = vector<Node>;

void Dfs(Tree &t, int node, vector<int> &st, int &nst)
{
	static int time = 0;
	st[nst++] = node;

	if (!t[node].ancestors.empty()) {
		int fa = t[node].ancestors[0];
		int power = 1;

		while ((1 << power) < nst) {
			t[node].ancestors.push_back(t[fa].ancestors[power - 1]);
			fa = t[fa].ancestors[power - 1];
			++power;
		}
	}

	for (int son : t[node].sons) {
		Dfs(t, son, st, nst);
	}
	t[node].exit_time = ++time;
	--nst;
}

void FindAncestors(Tree &t, int root)
{
	vector<int> st(t.size());
	int nst = 0;
	Dfs(t, root, st, nst);
}

int FindLca(const Tree &t, int x, int y)
{
	if (x == y) {
		return x;
	}

	if (t[x].exit_time > t[y].exit_time) {
		swap(x, y);
	}

	int pos = 0;
	int power = (1 << 20);

	while (power > 0) {
		if (pos + power < (int)t[x].ancestors.size()) {
			int fa = t[x].ancestors[pos + power];
			if (t[fa].exit_time <= t[y].exit_time) {
				pos += power;
			}
		}
		power >>= 1;
	}
	return FindLca(t, y, t[x].ancestors[pos]);
}

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

	int n, q;
	fin >> n >> q;

	Tree tree(n);
	for (int i = 1; i < n; ++i) {
		int fa;
		fin >> fa;
		tree[i].ancestors.push_back(fa - 1);
		tree[fa - 1].sons.push_back(i);
	}

	FindAncestors(tree, 0);

	while (q--) {
		int x, y;
		fin >> x >> y;
		fout << FindLca(tree, x - 1, y - 1) + 1 << "\n";
	}

	return 0;
}