Pagini recente » Cod sursa (job #3337402) | Borderou de evaluare (job #2027050) | Cod sursa (job #3331121) | Cod sursa (job #3275656) | Cod sursa (job #3327205)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX=1e5+1, EMAX=20;
int n, m;
vector <int> g[NMAX], lin;
int lvl[NMAX], s[NMAX], f[NMAX], rmq[EMAX][3*NMAX];
void dfs(int nod, int h){
lvl[nod]=h;
lin.push_back(nod);
rmq[0][lin.size()-1]=nod;
//cout<<lvl[rmq[0][lin.size()-1]]<<' ';
s[nod]=lin.size()-1;
for(int vec : g[nod]){
dfs(vec, h+1);
lin.push_back(nod);
rmq[0][lin.size()-1]=nod;
//cout<<lvl[rmq[0][lin.size()-1]]<<' ';
}
f[nod]=lin.size()-1;
}
bool comp(int x, int y){
return lvl[x]<lvl[y];
}
int main(){
fin>>n>>m;
for(int i=2;i<=n;i++){
int p;
fin>>p;
g[p].push_back(i);
}
lin.push_back(0);
dfs(1, 1);
/*cout<<endl;
for(int i=1;i<=n;i++){
cout<<i<<' '<<lvl[i]<<' '<<s[i]<<' '<<f[i]<<endl;
}*/
int len=lin.size(), lg[len];
lg[1]=0;
//cout<<len<<endl;
for(int i=2;i<len;i++)
lg[i]=lg[i/2]+1;
for(int e=1;e<=lg[len-1];e++){
//cout<<e<<endl;
for(int i=1;i<=len-(1<<e);i++){
if(comp(rmq[e-1][i], rmq[e-1][i+(1<<(e-1))]))
rmq[e][i]=rmq[e-1][i];
else
rmq[e][i]=rmq[e-1][i+(1<<(e-1))];
//cout<<i<<' '<<rmq[e][i]<<' '<<lvl[rmq[e][i]]<<endl;
}
}
while(m--){
int st, fi;
fin>>st>>fi;
//cout<<st<<' '<<fi<<endl;
st=s[st];
fi=s[fi];
if(st>fi){
swap(st,fi);
}
//cout<<st<<' '<<fi<<endl;
int e=lg[fi-st+1], ans;
//cout<<e<<endl;
if(comp(rmq[e][st], rmq[e][fi-(1<<e)+1]))
ans=rmq[e][st];
else
ans=rmq[e][fi-(1<<e)+1];
//cout<<ans<<endl;
fout<<ans<<'\n';
}
return 0;
}