Cod sursa(job #3144181)

Utilizator daristyleBejan Darius-Ramon daristyle Data 5 august 2023 20:37:34
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int N_MAX = 1e5;
const int EULER_DIM_MAX = 2 * N_MAX - 1;
const int LOG_MAX = 17;

template<typename T>
class OptimizedSparseTable{
private:
		T table[LOG_MAX][EULER_DIM_MAX];
		char lb[N_MAX + 1];

		T (* merge)(const T&, const T&);

public:
		OptimizedSparseTable(T (* func)(const T&, const T&)) : merge(func){}

		void build(int n, T v[]){
			lb[1] = 0;
			for(int i = 2; i <= n; ++i)
				lb[i] = lb[i / 2] + 1;

			for(int i = 0; i < n; ++i)
				table[0][i] = v[i];

			for(int e = 1; e < LOG_MAX; ++e)
				for(int i = 0; i + (1 << e) - 1 < n; ++i)
					table[e][i] = merge(table[e - 1][i], table[e - 1][i + (1 << (e - 1))]);
		}

		T query(int left, int right){
			int e = lb[right - left + 1];

			return merge(table[e][left], table[e][right - (1 << e) + 1]);
		}

		void print(int n){
			for(int e = 0; e < LOG_MAX; ++e){
				for(int i = 0; i < n; ++i)
					fout << table[e][i] << ' ';
				fout.put('\n');
			}
		}
};

int euler[EULER_DIM_MAX], eulerIndex;
int first[N_MAX], level[N_MAX];
vector<int> children[N_MAX];

void TourOfTree(int node){
	euler[eulerIndex] = node;
	first[node] = eulerIndex;
	++eulerIndex;

	for(auto child: children[node]){
		TourOfTree(child);

		euler[eulerIndex] = node;
		++eulerIndex;
	}
}

void ComputeLevel(int node, int lvl){
	level[node] = lvl;

	for(auto child: children[node])
		ComputeLevel(child, lvl + 1);
}

int min(const int& a, const int& b){
	return (level[a] < level[b]) ? a : b;
}

OptimizedSparseTable<int> rmq(min);

int LCA(int a, int b){
	if(first[a] > first[b])
		swap(a, b);
	return rmq.query(first[a], first[b]);
}

int main(){
	int n, queries, parent;
	fin >> n >> queries;

	for(int i = 1; i < n; ++i){
		fin >> parent;

		children[parent - 1].push_back(i);
	}

	eulerIndex = 0;
	TourOfTree(0);

	ComputeLevel(0, 0);

	rmq.build(2 * n - 1, euler);

	for(int i = 0; i < queries; ++i){
		fin >> n >> parent;

		fout << LCA(n - 1, parent - 1) + 1 << '\n';
	}

	fin.close();
	fout.close();
	return 0;
}