Pagini recente » Cod sursa (job #3363872) | Cod sursa (job #3363886) | Cod sursa (job #3363892) | Cod sursa (job #3363852) | Cod sursa (job #3363882)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
int n,m,k;
vector<int> adj[100005];
int level[100005];
int euler[200005];
int first_occ[100005];
int lg2[200005];
int rmq[18][200005];
void dfs(int node,int lvl) {
level[node]=lvl;
k++;
euler[k]=node;
first_occ[node]=k;
for (int child:adj[node]) {
dfs(child,lvl+1);
k++;
euler[k]=node;
}
}
int get_min(int node1,int node2) {
if (level[node1]<level[node2]) return node1;
return node2;
}
void build_rmq() {
for (int i=2; i<=k; i++) {
lg2[i]=lg2[i/2]+1;
}
for (int i=1; i<=k; i++) {
rmq[0][i]=euler[i];
}
for (int i=1; (1<<i)<=k; i++) {
for (int j=1; j+(1<<i)-1<=k; j++) {
rmq[i][j]=get_min(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]);
}
}
}
int query_lca(int u,int v) {
int l=first_occ[u];
int r=first_occ[v];
if (l>r) swap(l,r);
int len=r-l+1;
int j=lg2[len];
return get_min(rmq[j][l],rmq[j][r-(1<<j)+1]);
}
int main() {
cin>>n>>m;
for (int i=2; i<=n; i++) {
int parent;
cin>>parent;
adj[parent].push_back(i);
}
dfs(1,1);
build_rmq();
for (int i=1; i<=m; i++) {
int u,v;
cin>>u>>v;
cout<<query_lca(u,v)<<'\n';
}
}