Pagini recente » Cod sursa (job #1911589) | Cod sursa (job #1898216) | Cod sursa (job #543442) | Cod sursa (job #182354) | Cod sursa (job #2876010)
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int mx=2e5;
int n,q;
struct node{
int index,depth;
};
int lg2[mx],first[mx];
node rmq[20][mx];
vector<int> g[mx];
vector<node> euler;
void build_rmq(){
unsigned len=euler.size();
lg2[1]=0;
for(int i=2;i<mx;i++){
lg2[i]=lg2[i/2]+1;
}
for(int i=0;i<len;i++){
rmq[0][i]=euler[i];
}
for(int k=1;(1<<k)<=len;k++){
int now=(1<<k),old=(1<<(k-1));
for(int j=0;j<=len-now;j++){
node a=rmq[k-1][j],b=rmq[k-1][j+old];
rmq[k][j]=(a.depth<b.depth) ? a: b;
}
}
}
node query_rmq(int l, int r){
if(l>r){
swap(l,r);
}
int distance=(r-l+1);
int chunk=lg2[distance];
int chunk_size=1<<chunk;
node a=rmq[chunk][l];
node b=rmq[chunk][r-chunk_size+1];
return a.depth<b.depth?a:b;
}
void read(){
in>>n>>q;
int father;
for(int i=2;i<=n;i++){
in>>father;
g[father].push_back(i);
g[i].push_back(father);
}
}
void dfs(int node,int father,int depth){
for(int k:g[node]){
if(k==father)
continue;
euler.push_back({node,depth});
dfs(k,node,depth+1);
}
euler.push_back({node,depth});
}
void solve(){
dfs(1,0,0);
for(int i=0;i<mx;i++){
first[i]=-1;
}
for(int i=0;i<euler.size();i++){
if(first[euler[i].index]==-1){
first[euler[i].index]=i;
}
}
build_rmq();
int a,b;
while(q--){
in>>a>>b;
out<<query_rmq(first[a],first[b]).index<<'\n';
}
}
int main(){
read();
solve();
return 0;
}