Cod sursa(job #1923326)

Utilizator preda.andreiPreda Andrei preda.andrei Data 10 martie 2017 22:39:20
Problema Stramosi Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.62 kb
#include <cmath>
#include <fstream>
#include <stack>
#include <vector>

using namespace std;

struct Node
{
	vector<int> fathers;
	vector<int> sons;
};

using Tree = vector<Node>;

inline int Log(int n) { return log(n) / log(2); }

void Dfs(Tree &t, int node)
{
	stack<int> st;
	st.push(node);

	vector<bool> visited(t.size(), false);
	int level = 1;

	while (!st.empty()) {
		node = st.top();
		visited[node] = true;

		if (!t[node].fathers.empty()) {
			int fa = t[node].fathers[0];
			t[node].fathers.resize(Log(level));

			for (unsigned i = 1; i < t[node].fathers.size(); ++i) {
				t[node].fathers[i] = t[fa].fathers[i - 1];
				fa = t[node].fathers[i];
			}
		}

		bool new_son = false;
		for (int son : t[node].sons) {
			if (!visited[son]) {
				st.push(son);
				new_son = true;
				break;
			}
		}

		if (new_son) {
			++level;
		} else {
			st.pop();
			--level;
		}
	}
}

int FindAncestor(const Tree &t, int node, int l)
{
	while (l > 0 && !t[node].fathers.empty()) {
		unsigned pow = 0;
		while ((1 << pow) <= l && pow < t[node].fathers.size()) {
			++pow;
		}
		--pow;

		node = t[node].fathers[pow];
		l -= (1 << pow);
	}

	if (l > 0) {
		return -1;
	}
	return node;
}

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

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

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

	for (int i = 0; i < n; ++i) {
		if (tree[i].fathers.empty()) {
			Dfs(tree, i);
		}
	}

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

	return 0;
}