Pagini recente » Cod sursa (job #220430) | Cod sursa (job #1809104) | Cod sursa (job #3341141) | Cod sursa (job #2289126) | Cod sursa (job #3344198)
#include<iostream>
#include<vector>
using namespace std;
#define NMAX 100001
int n,q,fap[NMAX],d[NMAX],rmq[18][2*NMAX],_lg2[2*NMAX];
vector<int>g[NMAX],euler;
void dfs(int nod,int par){
d[nod]=d[par]+1;
fap[nod]=euler.size();
euler.push_back(nod);
for(const auto&son:g[nod]){
if(son==par)continue;
dfs(son,nod);
euler.push_back(nod);
}
}
void init_rmq(void){
n=euler.size()-1;
_lg2[0]=-1;
for(int i=1;i<=n;++i){
rmq[0][i]=euler[i];
_lg2[i]=1+_lg2[i>>1];
}
for(int k=1;(1<<k)<=n;++k){
for(int i=1;i+(1<<k)-1<=n;++i){
rmq[k][i]=(
d[rmq[k-1][i]]<d[rmq[k-1][i+(1<<(k-1))]]
?
rmq[k-1][i]
:
rmq[k-1][i+(1<<(k-1))]
);
}
}
// for(int k=0;(1<<k)<=n;++k){
// for(int i=1;i+(1<<k)-1<=n;++i){
// cout<<rmq[k][i]<<" ";
// }
// cout<<endl;
// }
}
signed main(){
#ifndef LOCAL
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#endif // LOCAL
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
cin>>n>>q;
// graph stuff
for(int i=2;i<=n;++i){
int x;
cin>>x;
g[x].push_back(i);
g[i].push_back(x);
}
euler.push_back(0);
dfs(1,0);
// init rmq
init_rmq();
// query stuff
for(;q;--q){
int x,y;
cin>>x>>y;
x=fap[x],y=fap[y];
if(x>y)swap(x,y);
int l=_lg2[y-x+1];
cout<<(
d[rmq[l][x]]<d[rmq[l][y-(1<<l)+1]]
?
rmq[l][x]
:
rmq[l][y-(1<<l)+1]
)<<"\n";
}
return 0;
}