Pagini recente » Cod sursa (job #3315074) | Cod sursa (job #3324465) | Cod sursa (job #3341198) | Cod sursa (job #3354049) | Cod sursa (job #3353686)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int const NMAX = 1e5 + 1;
int const LOGMAX = 18;
vector<int> fii[NMAX];
int euler[2*NMAX];
int nivele[2*NMAX];
int aparitii[NMAX];
int rmq[2*NMAX][LOGMAX];
int contor = 0;
void parcurgere(int nod, int nivel){
aparitii[nod] = contor;
euler[contor] = nod;
nivele[contor++] = nivel;
for(int fiu : fii[nod]){
parcurgere(fiu, nivel+1);
euler[contor] = nod;
nivele[contor++] = nivel;
}
}
void preprocesare(){
for(int i = 0; i < contor; i++){
rmq[i][0] = i;
}
for(int j = 1; (1<<j) <= contor; j++){
for(int i = 0; i+(1<<j) - 1 < contor; i++ ){
if(nivele[rmq[i][j - 1]] < nivele[rmq[i + (1 << (j - 1))][j - 1]])
rmq[i][j] = rmq[i][j - 1];
else
rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
}
}
}
int interogare(int a, int b){
int first_a = aparitii[a];
int first_b = aparitii[b];
if(first_a > first_b)
swap(first_a, first_b);
int lungime = first_b - first_a + 1;
int l = log2(lungime);
if(nivele[rmq[first_a][l]] < nivele[rmq[first_b - (1<<l) + 1][l]])
return euler[rmq[first_a][l]];
else
return euler[rmq[first_b - (1<<l) + 1][l]];
}
int main(){
int n, m;
fin>>n>>m;
for(int i = 2; i<=n; i++){
int x;
fin>>x;
fii[x].push_back(i);
}
parcurgere(1, 0);
preprocesare();
for(int i = 0; i < m; i++){
int a, b;
fin>>a>>b;
fout<<interogare(a, b)<<"\n";
}
}