Pagini recente » Cod sursa (job #27067) | Cod sursa (job #2959487) | Cod sursa (job #2945561) | Cod sursa (job #921222) | Cod sursa (job #3307113)
#include <bits/stdc++.h>
using namespace std;
const int K=18, N=1e5+5;
vector<int> eulerpath;
vector<int> adj[N];
bool vis[N];
int h[N], first[N], lg[2*N], lca[K][2*N];
void euler(int i){
eulerpath.push_back(i);
first[i]=eulerpath.size()-1;
vis[i]=true;
for (auto x: adj[i]){
if (!vis[x]){
euler(x);
eulerpath.push_back(i);
}
}
}
void dfs(int i, int d){
vis[i]=true;
h[i]=d;
for (auto x: adj[i]){
if (!vis[x]){
dfs(x, d+1);
}
}
}
int getlca(int l, int r){
if (l>r){
swap(l,r);
}
int i=lg[r-l+1];
int v1=lca[i][l];
int v2=lca[i][r-(1<<i)+1];
if (h[v1]<h[v2]){
return v1;
}
else{
return v2;
}
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdin);
lg[1]=0;
for (int i=2;i<2*N;i++){
lg[i]=lg[i/2]+1;
}
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;cin>>n>>m;
for (int i=2;i<=n;i++){
int a;cin>>a;
adj[a].push_back(i);
}
euler(1);
for (int i=1;i<=n;i++){
vis[i]=false;
}
dfs(1, 0);
n=eulerpath.size();
for (int i=0;i<n;i++){
lca[0][i]=eulerpath[i];
}
for (int i=1;i<K;i++){
for (int j=0;j+(1<<i)<=n;j++){
int v1=lca[i-1][j];
int v2=lca[i-1][j+(1<<(i-1))];
if (h[v1]<h[v2]){
lca[i][j]=v1;
}
else{
lca[i][j]=v2;
}
}
}
while (m--){
int u,v;cin>>u>>v;
u=first[u];
v=first[v];
cout<<getlca(u,v)<<'\n';
}
return 0;
}