Pagini recente » Cod sursa (job #3350391) | Cod sursa (job #2897319) | Cod sursa (job #2308520) | Cod sursa (job #3339022) | Cod sursa (job #3339215)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int> v[100001];
vector<int> euler;
vector<int> depth;
int lg[200001];
int rmq[200001][18];
int first[100001];
void dfs(int node,int d)
{
first[node]=euler.size();
euler.push_back(node);
depth.push_back(d);
for(auto it:v[node])
{
dfs(it,d+1);
euler.push_back(node);
depth.push_back(d);
}
}
void build_lg()
{
for(int i=2;i<=200000;i++)
{
lg[i]=lg[i/2]+1;
}
}
void build_rmq()
{
for(int i=0;i<euler.size();i++)
{
rmq[i][0]=i;
}
for(int j=1;(1<<j)<euler.size();j++)
{
for(int i=0;i+(1<<j)-1<euler.size();i++)
{
int a=rmq[i][j-1];
int b=rmq[i+(1<<(j-1))][j-1];
if(depth[a]>depth[b])
{
rmq[i][j]=b;
}
else rmq[i][j]=a;
}
}
}
int lca(int u,int v)
{
int a=first[u];
int b=first[v];
if(a>b) swap(a,b);
int sz=b-a+1;
int l=lg[sz];
int n1=rmq[a][l];
int n2=rmq[b-(1<<l)+1][l];
if(depth[n1]>depth[n2]) return euler[n2];
else return euler[n1];
}
int main()
{
int n,m;
fin>>n>>m;
for(int i=2;i<=n;i++)
{
int x;
fin>>x;
v[x].push_back(i);
}
dfs(1,1);
build_lg();
build_rmq();
for(int i=1;i<=m;i++)
{
int u,v;
fin>>u>>v;
fout<<lca(u,v)<<'\n';
}
return 0;
}