Pagini recente » Cod sursa (job #181949) | Cod sursa (job #3330548) | Cod sursa (job #2167774) | Cod sursa (job #1480459) | Cod sursa (job #3338613)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int Nmax = 100005;
const int Qmax = 100005;
const int Log2Nmax = 17;
struct nod{
int val;
vector<int> vecini;
int timp_initial, timp_final;
int timp_rmq, adancime;
};
struct pozitie_rmq{
int adancime, nod;
bool operator < (pozitie_rmq x){
return adancime < x.adancime;
}
};
int n, q, timp = 0, timp_rmq = 0;
int euler[2 * Nmax];
pozitie_rmq rmq_euler[Log2Nmax][2 * Nmax];
nod arbore[Nmax];
pozitie_rmq min(pozitie_rmq a, pozitie_rmq b){
if(a < b){
return a;
}
return b;
}
void citire_arbore(){
int nod;
fin >> n >> q;
for(int i = 2; i <= n; i++){
fin >> nod;
arbore[i].vecini.push_back(nod);
arbore[nod].vecini.push_back(i);
}
}
void liniarizare_euler(int nod, int parinte){
euler[++timp] = nod;
arbore[nod].timp_initial = timp;
rmq_euler[0][++timp_rmq] = {arbore[nod].adancime, nod};
arbore[nod].timp_rmq = timp_rmq;
for(int vecin : arbore[nod].vecini){
if(vecin != parinte){
arbore[vecin].adancime = arbore[nod].adancime + 1;
liniarizare_euler(vecin, nod);
rmq_euler[0][++timp_rmq] = {arbore[nod].adancime, nod};
}
}
euler[++timp] = nod;
arbore[nod].timp_final = timp;
}
void calculare_rmq(){
for(int bit = 1; (1 << bit) <= timp; bit++){
for(int i = 1; i <= timp - (1 << bit) + 1; i++){
rmq_euler[bit][i] = min(rmq_euler[bit - 1][i], rmq_euler[bit - 1][i + (1 << (bit - 1))]);
}
}
}
pozitie_rmq rmq_query(int poz1, int poz2){
int ordin = log2(poz2 - poz1);
return min(rmq_euler[ordin][poz1], rmq_euler[ordin][poz2 - (1 << ordin) + 1]);
}
int lca(int nod1, int nod2){
return rmq_query(arbore[nod1].timp_rmq, arbore[nod2].timp_rmq).nod;
}
void citire_si_rezolvare_interogari(){
int nod1, nod2;
for(int i = 1; i <= q; i++){
fin >> nod1 >> nod2;
if(arbore[nod1].timp_rmq > arbore[nod2].timp_rmq){
swap(nod1, nod2);
}
fout << lca(nod1, nod2) << '\n';
}
}
int main(){
citire_arbore();
liniarizare_euler(1, 0);
calculare_rmq();
citire_si_rezolvare_interogari();
return 0;
}