Pagini recente » Cod sursa (job #3327033) | Cod sursa (job #924368) | Cod sursa (job #3304357) | Cod sursa (job #3356134) | Cod sursa (job #3342740)
#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 putere_2[200000 + 5];
vector<element_euler> rmq[200000 + 5];
void generate_puteri_2(){
putere_2[1] = 0;
for(int i = 2; i <= 2 * num_noduri; i++){
putere_2[i] = putere_2[i / 2] + 1;
}
}
void build_rmq(){
for(int i = 1; i < euler_tour.size(); i++){
rmq[i].push_back(euler_tour[i]);
}
for(int exponent = 1; exponent <= putere_2[euler_tour.size() - 1]; 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].push_back(st);
}
else{
rmq[i].push_back(dr);
}
}
}
}
element_euler minim(int capat_st, int capat_dr){
int lungime = capat_dr - capat_st + 1;
int exponent = putere_2[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 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;
int capat_st = min(prima_aparitie[nod_1], prima_aparitie[nod_2]);
int capat_dr = max(prima_aparitie[nod_1], prima_aparitie[nod_2]);
fout << minim(capat_st, capat_dr).valoare << '\n';
}
return 0;
}