Link to this code:
https://cses.fi/paste/c9021b5fdb5a15381042488/#include <bits/stdc++.h>
using namespace std;
int main() {
cin.tie(0)->sync_with_stdio(0);
int n,q;
cin>>n>>q;
vector<vector<int>> adj(n);
for (int i = 1; i < n; i++) {
int par;
cin>>par;
par--;
adj[par].push_back(i);
}
vector<int> depth(n);
vector<int> pre_order(n);
vector<int> time_in(n);
vector<int> time_out(n);
int timer = 0;
auto dfs = [&](auto dfs, int u) -> void {
time_in[u] = timer;
pre_order[timer++] = u;
for(int v : adj[u]) {
depth[v] = 1 + depth[u];
dfs(dfs, v);
}
time_out[u] = timer;
};
dfs(dfs, 0);
vector<int> seg_tree(2 * n);
for (int i = 0; i < n; i++) {
seg_tree[n + i] = time_out[pre_order[i]];
}
for (int i = n-1; i >= 1; i--) {
seg_tree[i] = max(seg_tree[2*i], seg_tree[2*i+1]);
}
auto lca = [&](int u, int v) -> int {
if(time_in[u] > time_in[v]) swap(u, v);
int l = 1, r = time_in[u]+1;
while(l < r) {
int w = r + n, b = __lg(min(w & -w, r - l));
if (seg_tree[(w-1) >> b] <= time_in[v]) r -= 1 << b;
else l = r - (1 << b) + 1;
}
return pre_order[l-1];
};
while(q--) {
int u,v;
cin>>u>>v;
u--,v--;
cout<<lca(u,v)+1<<'\n';
}
return 0;
}