Pagini recente » Cod sursa (job #523167) | Borderou de evaluare (job #1047029) | Cod sursa (job #473101) | Cod sursa (job #3268499) | Cod sursa (job #3228441)
//trebuie sa stiu
//pozitia nodului
//nivelul nodului
//fac rmq pe sirul care este
//turul lui euler
//in dp[i][j] retin nodul de pe nivelul cel mai mic
//[i,i+2^j-1]
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int MAXVAL=200000,putere=17,val=100000;
int dp[MAXVAL+1][putere+1],nivel[val+1],poz[val+1],log_2[MAXVAL+1];
vector<vector<int>>gr(val+1);
vector<int>euler;
void dfs(const int& nod,int niv){
euler.push_back(nod);
nivel[nod]=niv;
poz[nod]=euler.size()-1;
for(const auto&x:gr[nod]){
dfs(x,niv+1);
euler.push_back(nod);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m,nr;
cin>>n>>m;
for(int i=2;i<=n;i++){
cin>>nr;
gr[nr].push_back(i);
}
dfs(1,0);
for(int i=0;i<euler.size();i++){
dp[i][0]=euler[i];
}
for(int i=2;i<=euler.size();i++){
log_2[i]=log_2[i/2]+1;
}
for(int i=euler.size()-1;i>=0;i--){
for(int j=1;i+(1<<j)-1<=euler.size()-1;j++){
if(nivel[dp[i][j-1]]<nivel[dp[i+(1<<(j-1))][j-1]]){
dp[i][j]=dp[i][j-1];
}else{
dp[i][j]=dp[i+(1<<(j-1))][j-1];
}
}
}
int a,b,l;
for(int i=1;i<=m;i++){
cin>>a>>b;
a=poz[a];
b=poz[b];
if(a>b){
swap(a,b);
}
l=log_2[b-a+1];
if(nivel[dp[a][l]]<nivel[dp[b-(1<<l)+1][l]]){
cout<<dp[a][l]<<'\n';
}else{
cout<<dp[b-(1<<l)+1][l]<<'\n';
}
}
}