Cod sursa(job #3237778)

Utilizator luc3lexaAlexandrescu Luca luc3lexa Data 13 iulie 2024 00:58:35
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.74 kb
#include <iostream>
#include <fstream>
#include <bits/stdc++.h>
using namespace std;

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

const int nmax = 1e5+10;
int n,m,pos;
vector<int> values(nmax,0),level(2*nmax,0),first(nmax,0),euler;
vector<int> visited(nmax,0),lg(nmax,0);
vector<vector<int>> mat(nmax);
int rmq[20][2*nmax];

void read_input(){
	fin >> n >> m;
	int aux;
	for(int i = 1; i <=n-1; i++){
		fin >> aux;
		mat[aux].push_back(i+1);
	}
};

void dfs(int nod,int lev){
    
	visited[nod] = 1;
	euler.push_back(nod);
	level[euler.size()] = lev;
	first[nod] = euler.size();
	
	for(auto nod_aux : mat[nod]){
		if(!visited[nod_aux]){
		    
			dfs(nod_aux,lev+1);
			euler.push_back(nod);
			level[euler.size()] = lev;
			
		}
	}
}
void RMQ(int value){
	lg[1] = 0;
	for(int i = 2; i <= value; i++){
		lg[i] = 1+lg[i/2];
	};
	for(int i = 1; i <= value; i++){
		rmq[0][i] = i;
	}
	for(int putere = 1; (1 << putere) <= value; putere++){
		for(int i = 1; i  <=value; i++){
			int j = i + (1 << (putere-1));
			if(j <= value){
			    rmq[putere][i] = rmq[putere-1][i];
			    if(level[rmq[putere][i]] > level[rmq[putere-1][j]]){
					rmq[putere][i] = rmq[putere-1][j];
			    }
			}
		}
	}
}
int main(){
	read_input();
	dfs(1,1);
	RMQ((int)euler.size());
	int nod_1,nod_2;
	for(int i = 1;i <=m; i++){
		fin >> nod_1 >> nod_2;
		int index_1 = first[nod_1];
		int index_2 = first[nod_2];
		if(index_1 > index_2) swap(index_1, index_2);
		
		int length = index_2-index_1+1;
		int exponent = lg[length];
		long long int power = (1 << lg[length]);
		
		int ans = level[rmq[exponent][index_1]];
		int index = rmq[exponent][index_1];
		if(level[rmq[exponent][index_2-power+1]] < ans){
			index = rmq[exponent][index_2-power+1];
		};
		fout << euler[index-1] << '\n';
	};
	return 0;
}