Pagini recente » Cod sursa (job #50762) | Cod sursa (job #2749291) | Cod sursa (job #2915459) | Cod sursa (job #2131183) | Cod sursa (job #1943173)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n,qs;
vector<int> L[100005];
int EULER[2*100005], NIV[2*100005],FOCC[100005],es;
int RMQ[20][2*100005];
int LOG2[2*100005];
void read(){
int x;
in>>n>>qs;
for(int i=1;i<n;i++){
in>>x;
L[x].push_back(i+1);
L[i+1].push_back(x);
}
}
void dfs(int st, int par, int niv){
es++;
EULER[es]=st;
NIV[es]=niv;
if(FOCC[st]==0) // first occurrence
FOCC[st]=es;
for(auto x : L[st]){
if(x!=par){ // no going back ;)
dfs(x,st,niv+1);
es++;
EULER[es]=st;
NIV[es]=niv;
}
}
}
void prep(){
for(int i=1;i<=es;i++){
RMQ[0][i]=i;
}
for(int i=1;(1<<i)<=es;i++){
for(int j=1;j<=es;j++){
if(NIV[RMQ[i-1][j]]<NIV[RMQ[i-1][j+(1<<(i-1))]]){
RMQ[i][j]=RMQ[i-1][j];
}
else{
RMQ[i][j]=RMQ[i-1][j+(1<<(i-1))];
}
}
}
}
void logs(){
for(int i=2;i<=es;i++){
LOG2[i]=LOG2[i/2]+1;
}
}
int query(int x, int y){
int lo,hi,log,nelem;
lo=min(x,y);
hi=max(x,y);
nelem=hi-lo+1;
log=LOG2[nelem];
if(NIV[RMQ[log][lo]]<NIV[RMQ[log][lo+nelem-(1<<log)]]){
return RMQ[log][lo];
}
else{
return RMQ[log][lo+nelem-(1<<log)];
}
}
void solve(){
int x,y;
dfs(1,-1,0);
prep();
logs();
for(int i=1;i<=qs;i++){
in>>x>>y;
out<<EULER[query(FOCC[x],FOCC[y])]<<"\n";
}
}
int main(){
read();
solve();
return 0;
}