Pagini recente » Cod sursa (job #2548737) | Cod sursa (job #215967) | Cod sursa (job #1512038) | Cod sursa (job #821937) | Cod sursa (job #3040449)
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100005
#define MAXLOG 20
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
struct RmqItem{
int nod;
int nivel;
};
RmqItem rmq[MAXLOG][2*NMAX];
vector <int> arb[NMAX];
int n, m, tata, nod1, nod2, pcurent, pstart[NMAX], exp[2*NMAX];
void dfs(int nod, int niv){
rmq[0][++pcurent] = {nod, niv};
pstart[nod] = pcurent;
for(int i = 0; i < arb[nod].size(); i++){
dfs(arb[nod][i], niv+1);
rmq[0][++pcurent] = {nod, niv};
}
}
// Exponentul celei mai mari puteri ale lui 2 mai mici sau egale cu i
void calculExponent(){
exp[1] = 0;
for(int i = 2; i <= pcurent; i++){
exp[i] = 1 + exp[i/2];
}
}
void calculRMQ(){
int pmax = exp[pcurent];
for(int p = 1; p <= pmax; p++){
for(int i = 1; i <= pcurent; i++){
int j = i + (1 << (p-1));
rmq[p][i] = rmq[p-1][i];
if(j <= pcurent && rmq[p-1][j].nivel < rmq[p][i].nivel){
rmq[p][i] = rmq[p-1][j];
}
}
}
}
int LCA(int x, int y){
int poz_x = pstart[x];
int poz_y = pstart[y];
if(poz_x > poz_y){
swap(poz_x, poz_y);
}
int lungime = poz_y - poz_x + 1;
int e = exp[lungime];
int l = (1 << e);
RmqItem st = rmq[e][poz_x];
RmqItem dr = rmq[e][poz_y - l + 1];
return (st.nivel < dr.nivel) ? st.nod : dr.nod;
}
int main()
{
in >> n >> m;
for(int nod = 2; nod <= n; nod++){
in >> tata;
arb[tata].push_back(nod);
}
dfs(1,1);
calculExponent();
calculRMQ();
for(int i = 1; i <= m; i++){
in >> nod1 >> nod2;
out << LCA(nod1, nod2) << '\n';
}
return 0;
}