Pagini recente » Cod sursa (job #2088840) | Cod sursa (job #1876984) | Cod sursa (job #1072126) | Cod sursa (job #1776474) | Cod sursa (job #3342762)
#include <vector>
#include <fstream>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int num_noduri, num_queries;
int tata;
vector<int> adiacenta[100000 + 5];
int nod_1, nod_2;
struct element_euler{
int valoare, nivel;
};
vector<element_euler> euler_tour;
int prima_aparitie[100000 + 5];
void initialize(){
euler_tour.push_back({0, 0});
for(int i = 1; i <= num_noduri; i++){
prima_aparitie[i] = 1e9;
}
}
void build_euler_tour(int nod = 1, int nivel = 1){
euler_tour.push_back({nod, nivel});
prima_aparitie[nod] = min(prima_aparitie[nod], (int)euler_tour.size() - 1);
for(int fiu : adiacenta[nod]){
build_euler_tour(fiu, nivel + 1);
euler_tour.push_back({nod, nivel});
}
}
int log[200000 + 5];
element_euler rmq[200000 + 5][20];
void generate_puteri_2(){
log[1] = 0;
for(int i = 2; i <= 2 * num_noduri; i++){
log[i] = log[i / 2] + 1;
}
}
void build_rmq(){
int euler_tour_size = euler_tour.size() - 1;
for(int i = 1; i <= euler_tour_size; i++){
rmq[i][0] = euler_tour[i];
}
for(int exponent = 1; exponent <= log[euler_tour_size]; exponent++){
int pow_2 = (1 << exponent);
for(int i = 1; i + pow_2 <= euler_tour_size; i++){
element_euler st = rmq[i][exponent - 1];
element_euler dr = rmq[i + pow_2 / 2][exponent - 1];
if(st.nivel <= dr.nivel){
rmq[i][exponent] = st;
}
else{
rmq[i][exponent] = dr;
}
}
}
}
element_euler minim(int capat_st, int capat_dr){
int lungime = capat_dr - capat_st + 1;
int exponent = log[lungime];
int pow_2 = (1 << exponent);
element_euler st = rmq[capat_st][exponent];
element_euler dr = rmq[capat_dr - pow_2 + 1][exponent];
if(st.nivel <= dr.nivel){
return st;
}
else{
return dr;
}
}
int lca(int nod_1, int nod_2){
int capat_st = min(prima_aparitie[nod_1], prima_aparitie[nod_2]);
int capat_dr = max(prima_aparitie[nod_1], prima_aparitie[nod_2]);
return minim(capat_st, capat_dr).valoare;
}
int main(){
fin >> num_noduri >> num_queries;
for(int i = 2; i <= num_noduri; i++){
fin >> tata;
adiacenta[tata].push_back(i);
}
initialize();
build_euler_tour();
generate_puteri_2();
build_rmq();
for(int i = 1; i <= num_queries; i++){
fin >> nod_1 >> nod_2;
fout << lca(nod_1, nod_2) << '\n';
}
return 0;
}