Pagini recente » Cod sursa (job #2363991) | Cod sursa (job #2840073)
#include <bits/stdc++.h>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector<int> v[100002];
int aint[1000001],dp[300000],parc[100001],n,m,first[100001],liniarizare[300001];
int cat;
void dfs(int nod)
{
parc[nod]=1;
for(auto nod2 : v[nod])
if(parc[nod2]==0)
{
dp[nod2]=dp[nod]+1;
dfs(nod2);
}
}
void build(int nod,int l,int r){
if(l>r)
return;
if(l==r){
aint[nod]=liniarizare[l];
return;
}
int mij=(l+r)/2;
build(nod*2,l,mij);
build(nod*2+1,mij+1,r);
if(dp[aint[2*nod]]<dp[aint[2*nod+1]])
aint[nod]=aint[2*nod];
else
aint[nod]=aint[2*nod+1];
}
int query(int nod,int l, int r, int x, int y){
if(y<l || x>r || l>r)
return -1;
if(x<=l && r<=y)
return aint[nod];
int mij=(l+r)/2;
int a=query(nod*2,l,mij,x,y);
int b=query(nod*2+1,mij+1,r,x,y);
if(a==-1)
return b;
if(b==-1)
return a;
if(dp[a]<dp[b])
return a;
else
return b;
}
void euler(int nod){
++cat;
liniarizare[cat]=nod;
first[nod]=cat;
parc[nod]=1;
for(auto nod2 : v[nod])
if(parc[nod2]==0)
{
euler(nod2);
++cat;
liniarizare[cat]=nod;
}
}
int main()
{
int i,j,x,a,b;
in>>n>>m;
for(i=2;i<=n;++i){
in>>x;
v[x].push_back(i);
}
dfs(1);
for(i=1;i<=n;++i)
parc[i]=0;
dp[0]=1e8;
euler(1);
build(1,1,2*n-1);
for(i=1;i<=m;++i)
{
in>>a>>b;
a=first[a];
b=first[b];
out<<query(1,1,2*n-1,min(a,b),max(a,b))<<'\n';
}
return 0;
}