Pagini recente » Cod sursa (job #1884549) | Cod sursa (job #1267376) | Cod sursa (job #2086343) | Cod sursa (job #620839) | Cod sursa (job #3306423)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n,m,x, lg[400005], first[100005];
vector<int> v[100005];
vector<pair<int,int>> euler;
pair<int,int> rmq[400005][20];
void dfs(int nod, int niv){
euler.push_back({niv,nod});
if(first[nod]==-1)
first[nod]=euler.size()-1;
for(auto neigh: v[nod]){
dfs(neigh, niv+1);
euler.push_back({niv, nod});
}
}
int query(int a, int b){
int l=lg[b-a+1];
return min(rmq[a][l], rmq[b-(1<<l)+1][l]).second;
}
int main()
{
cin>>n>>m;
for(int i=2; i<=n;i++){
cin>>x;
v[x].push_back(i);
}
for(int i=1; i<=n;i++)
first[i]=-1;
dfs(1,1);
int indx=0;
for(auto u: euler){
rmq[indx][0]=u;
indx++;
}
int ne=euler.size()-1;
for(int i=2; i<=ne;i++){
lg[i]=lg[i-1];
if(!(i&(i-1))) lg[i]++;
}
for(int j=1; (1<<j)<=ne; j++)
for(int i=0; i+(1<<j)-1<=ne; i++)
rmq[i][j]=min(rmq[i][j-1], rmq[i+(1<<(j-1))][j-1]);
int a,b;
while(m--){
cin>>a>>b;
a=first[a];
b=first[b];
if(a>b) swap(a,b);
cout<<query(a, b)<<'\n';
}
return 0;
}