Cod sursa(job #1849247)

Utilizator SmarandaMaria Pandele Smaranda Data 17 ianuarie 2017 10:47:20
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

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

const int N = 100003;

vector <int> graph [N];
int l [2 * N + 1], first [N], level[N], lg2 [N];
pair <int, int> rmq [18][N];
bool used[N];

void dfs(int x){
	vector<int> :: iterator it;

	used [x] = true;
	l [++ l [0]] = x;
	first [x] = l [0];
	for (it = graph [x].begin(); it != graph [x].end(); ++it)
		if (!used [*it]){
			level [*it] = level [x] + 1;
			dfs(*it);
			l [++ l [0]] = x;
		}
}

pair <int, int> myMin(pair <int, int> A, pair <int, int> B){
	if (A.first < B.first)
		return A;
	return B;
}

void RMQ(){
	int i, j, len, len2, nextP2;

	for (i = 1; i <= l[0]; i++) 
		rmq [0][i] = make_pair(level [l [i]], l [i]);
	lg2 [0] = 0;
	nextP2 = 2;
	for (i = 1; i <= l[0]; i++){
		lg2 [i] = lg2 [i - 1];
		if (i == nextP2){
			lg2 [i]++;
			nextP2 = nextP2 << 1;
		}
	}
	for (i = 1; (1 << i) <= l[0]; i++) {
		len2 = (1 << (i - 1));
		for (j = 1; j <= l [0] - (1 << i) + 1; j++) {
			rmq [i][j] = myMin(rmq [i - 1][j], rmq [i - 1][j + len2]);
		}
	}
}

int main(){
	int n, m, i, x, y, len, j;
	pair <int, int> ans;

	cin >> n >> m;
	for (i = 2; i <= n; i++){
		cin >> x;
		graph [x].push_back(i);
	}
	dfs(1);
	RMQ();
	for (i = 0; i < m; i++) {
		cin >> x >> y;
		x = first [x];
		y = first [y];
		if (x > y)
			swap(x, y);
		len = (y - x + 1);
		j = lg2 [len];

		ans = myMin(rmq [j][x], rmq [j][y - (1 << j) + 1]);
		cout << ans.second << "\n";
	}
	return 0;
}