Cod sursa(job #1482734)

Utilizator tain1234andrei laur tain1234 Data 7 septembrie 2015 20:49:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <vector>
#include <map>
#include <fstream>
int i = 0, root = 1;
const int lg = 40;
const int o = 200000 + 20;
int e[o], d[o], h[o], c[o][lg];
using namespace std;
class tree{
public:
	map<int,vector<int>> N;
	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 preprocess(){
		euler(root, 0,i);
		rmq2();
	}
	void rmq2(){
		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, pow = 1;
		while (pow <= p2 - p1 + 1){ pow <<= 1; ++k; }
		pow >>= 1;
		--k;
		int index = d[c[p1][k]] <= d[c[p2 - pow + 1][k]] ? c[p1][k] : c[p2 - pow + 1][k];
		return e[index];
	}
	void add(int&a, int&b){
		N[a].push_back(b);
	}
};
int main(){
	ifstream f ("lca.in");
	ofstream g("lca.out");
int n, m,x;
	std::fill_n(h, o, -1);
	f >> n >> m;
	tree t;
	for (int i = 2; i <= n; ++i){
		f >> x;
		t.add(x, i);
	}
	t.preprocess();
	for (int i = 0; i < m; ++i){
		f >> n >> x;
		g << t.lca(n, x) << "\n";
	}
	return 0;
}