Cod sursa(job #2921754)

Utilizator alt_contStefan alt_cont Data 1 septembrie 2022 18:41:15
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.17 kb
#include <fstream>
#include <iostream>
#include <vector>
#define MAX 100010
using namespace std;

int parent[MAX];
vector<int> tree[MAX];
int t = 0;
vector<int> ans;
vector<int> idxs(4*MAX);
vector<int> d(4*MAX);
int rmqcache[4*MAX + 20][25];
int rmqcache2[4*MAX + 20][25];

void visit(int i, int depth){

	ans.push_back(i);
	
	idxs[i] = t; 
	d[t] = depth;
	++t;
	for(auto x: tree[i]){
		visit(x, depth + 1);
		ans.push_back(i);
		d[t] = depth;
		++t;
	}
}

void rmq_preprocess(int n, int sz){
	int logarithm = 0;
	while(n){
		n = n/2;
		++logarithm;
	}

	//cout << "MAX_LOG" << sz << endl;

	for(int i = 0; i < sz; ++i){
		rmqcache[i][0] = i;
		rmqcache2[i][0] = i;
	}

	for(int k = 1; k <= logarithm; ++k)
	 	for(int i = 0; i < sz; ++i){
	 		if(i + (1 << (k - 1)) < sz)
				rmqcache[i][k]  = (d[rmqcache[i][k - 1]] < d[rmqcache2[i + (1 << (k - 1))][k - 1]]) ? rmqcache[i][k - 1] : rmqcache2[i + (1 << (k - 1))][k - 1];
			if(i - (1 << (k - 1)) >= 0)
	 			rmqcache2[i][k] = (d[rmqcache2[i][k - 1]]  < d[rmqcache[i - (1 << (k - 1))][k - 1]]) ? rmqcache2[i][k - 1] : rmqcache[i - (1 << (k - 1))][k - 1];
	 	}
}


int rmq(int ia, int ib){
	int diff = ib - ia;
	int logarithm = 0;
	while(diff){
		diff = diff/2;
		++logarithm;
	}

	//cout << ia <<" " << ib << " " << (ia + (1 << (logarithm - 1))) << " " << (ib - (1 << (logarithm - 1))) << " " << logarithm << endl;

	return d[rmqcache[ia][logarithm]] < d[rmqcache2[ib][logarithm]] ? rmqcache[ia][logarithm] : rmqcache2[ib][logarithm];

}
 
	
int main(){
	ifstream fin;
	ofstream fout;
	fin.open("lca.in");
	fout.open("lca.out"); 
	int m, n, a, b;
	int v[2*MAX];
	
	fin >> n >> m;
	for(int i = 2; i <= n; ++i){
		fin >> parent[i];
		tree[parent[i]].push_back(i);
	}


	visit(1, 1);
	rmq_preprocess(2 * n, ans.size());
	// for(int i = 0; i < ans.size(); ++i)
	// 	cout << d[i] << " ";

	// cout << endl;

	// for(int i = 0; i < ans.size(); ++i)
	// 	cout << ans[i] << " ";
	// cout << endl;

	for(int i = 0; i < m; ++i){
		int a, b;
		fin >> a >> b;
		if(idxs[a] > idxs[b])
			swap(a, b);

		int ia = idxs[a];
		int ib = idxs[b];

		fout << ans[rmq(ia, ib)] << "\n";
	}		

}