Cod sursa(job #1456213)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 30 iunie 2015 00:33:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include <fstream>
#include <array>
#include <vector>
#include <cmath>
using namespace std;

void make_euler(const vector<vector<int> >& fii,
	vector<int>& euler, vector<int>& first_aparition,
	vector<int>& adanc, const int cur = 0, const int ad_cur = 0){
	first_aparition[cur] = euler.size();
	euler.push_back(cur);
	adanc[cur] = ad_cur;
	for(const auto next : fii[cur]){
		make_euler(fii, euler, first_aparition, adanc, next, ad_cur+1);
		euler.push_back(cur); } }

template <typename Cmp>
class rmq{
	vector<array<int, 19> > buf;
	Cmp cmp;
public:
	rmq(const vector<int>& v, Cmp c):
		buf(v.size()),
		cmp(c){
		for(int i = 0; i < buf.size(); ++i){
			buf[i][0] = v[i]; }
		for(int adanc = 1; adanc < 19; ++adanc){
			const int marime = 1<<adanc,
				delta = 1<<(adanc-1);
			for(int i = 0; i+marime <= buf.size(); ++i){
				buf[i][adanc] = min(buf[i][adanc-1],
					buf[i+delta][adanc-1],
					cmp); } } }
	int query(const int st, const int dr){
		const int marime = log2(dr-st+1),
			delta = 1<<marime;
		return min(buf[st][marime], buf[dr-delta+1][marime]); } };

int main(){
	ifstream f("lca.in");
	ofstream g("lca.out");
	int n, m;
	f >> n >> m;
	vector<vector<int> > fii(n);
	vector<int> euler, first_aparition(n), adanc(n);
	euler.reserve(2*n);
	for(int i = 1, x; i < n; ++i){
		f >> x;
		fii[x-1].push_back(i); }
	auto cmp = [&adanc](const int a, const int b){
		return adanc[a] < adanc[b]; };
	make_euler(fii, euler, first_aparition, adanc);
	rmq<decltype(cmp)> r(euler, cmp);
	for(int i = 0, a, b; i < m; ++i){
		f >> a >> b;
		--a, --b;
		if(first_aparition[a] > first_aparition[b]){
			swap(a, b); }
		g << (r.query(first_aparition[a], first_aparition[b])+1) << '\n'; }
	return 0; }