Cod sursa(job #1488903)

Utilizator DacianBocea Dacian Dacian Data 20 septembrie 2015 01:54:54
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.3 kb
#include <vector>
#include <map>
#include <fstream>
#include <cstring>
int i = 0, root = 1;
const int lg = 40;
const int o = 200020;
int e[o], d[o], h[o], c[o][lg];
using namespace std;

vector<int>N[100002];

void euler(int& current, int dist, int& i){
	e[i] = current;
	d[i] = dist;
	if (h[current] == -1)h[current] = i;
	for (auto& k : N[current]){
		++i;
		euler(k, dist + 1, i);
		++i;
		e[i] = current;
		d[i] = dist;
	}
}
void rmq(){
	int j, N = i;
	for (i = 0; i < N; ++i)
		c[i][0] = i;
	for (j = 1; 1 << j <= N; ++j)
	for (i = 0; i + (1 << j) - 1 < N; ++i)
	if (d[c[i][j - 1]] < d[c[i + (1 << (j - 1))][j - 1]])
		c[i][j] = c[i][j - 1];
	else
		c[i][j] = c[i + (1 << (j - 1))][j - 1];
}
int lca(int& a, int& b){
	int p1 = h[a], p2 = h[b];
	if (p2 < p1){
		p1 ^= p2; p2 = p1^p2; p1 ^= p2;
	}
	int k = 0, p = 1;
	while (p <= p2 - p1 + 1){ p <<= 1; ++k; }
	p >>= 1;
	--k;
	int index = d[c[p1][k]] <= d[c[p2 - p + 1][k]] ? c[p1][k] : c[p2 - p + 1][k];
	return e[index];
}
int main(){
	ifstream f("lca.in");
	ofstream g("lca.out");
	int n, m, x;
	memset(h, -1, sizeof(h));
	f >> n >> m;
	for (int i = 2; i <= n; ++i){
		f >> x;
		N[x].push_back(i); 
	}
	euler(root, 0, i);
	rmq();
	for (int i = 0; i < m; ++i){
		f >> n >> x;
		g << lca(n, x) << "\n";
	}
	return 0;
}