Pagini recente » Cod sursa (job #2503947) | Cod sursa (job #2593069) | Cod sursa (job #3226353) | Cod sursa (job #1695824) | Cod sursa (job #2641207)
#include<bits/stdc++.h>
using namespace std;
#define INIT ios_base :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define mp make_pair
#define pb push_back
#define ft first
#define sc second
#define ll long long
#define pii pair<int, int>
#define count_bits __builtin_popcount
#define int ll
#define pow pw
int t, n, m, k, a[300010], q, l, r;
ifstream fin("lca.in"); ofstream fout("lca.out");
#define cin fin
#define cout fout
vector<pii> tour;
int dpt[100010];
int ft[100010];
vector<vector<int>> g;
int p[100010];
pii rmq[22][100010];
vector<int> pow;
void euler(){
dpt[1]=1;
stack<int> s;
s.push(1);
while(!s.empty()){
int top=s.top();
if(ft[top]==0){
ft[top]=((int)tour.size());
}
dpt[top]=dpt[p[top] ]+1;
tour.pb(mp(dpt[top],top) );
for(;g[top].size()>0;){
s.push(g[top].back());
g[top].pop_back();
goto Next;
}
s.pop();
if(p[top]!=0){
s.push(p[top]);}
if(ft[top]==0){
ft[top]=((int)tour.size())-1;
}
Next:continue;
}
}
void RMQ(){
for(int j=0; (((int)1)<<j)<tour.size(); j++){
for(int i=0; i<tour.size(); i++){
if(j==0){
rmq[j][i]=tour[i];
}
else{
if( (i+( ((int)1)<<(j) ))<(tour.size()) ){
if(rmq[j-1][i].ft<=rmq[j-1][i+(((int)1)<<(j-1)) ].ft){
rmq[j][i]=rmq[j-1][i];
}
else{
rmq[j][i]=rmq[j-1][i+(((int)1)<<(j-1) )];
}
}
}
}
}
pow.resize( (tour.size()+10) );
int temp=0;
for(int i=1; i<pow.size(); i++){
if(i>=(((int)1)<<((int)temp+1)) ){temp++;}
pow[i]=temp;
}
}
int LCA(int u, int v){
int x=ft[u], y=ft[v];
if(y<x){swap(x, y);}
int l=y-x;
int j=pow[l];
if(rmq[j][x].ft<=rmq[j][y-(((int)1)<<j)+1].ft){
return rmq[j][x].sc;
}
else{
return rmq[j][y-(((int)1)<<j)+1].sc;
}
}
int32_t main(){
INIT
cin>>n>>m;
g.resize(n+5);
for(int i=1; i<n; i++){
cin>>p[i+1];
g[p[i+1] ].pb(i+1);
}
euler(); RMQ();
/*for(int i=0; i<tour.size(); i++){cout<<tour[i].sc<<" ";}
cout<<"\n";*/
for(int i=1; i<=m; i++){
int u,v;
cin>>u>>v;
cout<<LCA(u, v)<<"\n";
}
return 0;
}