Pagini recente » Cod sursa (job #30630) | Cod sursa (job #3254985) | Cod sursa (job #129065) | Cod sursa (job #2285532) | Cod sursa (job #1257489)
#include<cstdio>
#include<vector>
using namespace std;
vector<int> a[1000002];
int y,niv[200003],i,n,m,x,nr,rmq[21][400002],elr[200002],ap[100002],lg[200003];
void rmy()
{
for(int i=2; i<=nr; ++i)
lg[i]=lg[i >> 1]+1;
for(int i=1; i<=nr; ++i)
rmq[0][i]=i;
for(int i=1; (1 << i)<nr; ++i)
for(int j=1; j<=nr-(1 << i); ++j)
{
int l=1 << (i - 1);
rmq[i][j]=rmq[i-1][j];
if(niv[rmq[i-1][j + l]]<niv[rmq[i][j]])
rmq[i][j]=rmq[i-1][j + l];
}
}
int lca(int x,int y)
{
int a,b,dif,q,l,sol;
a=ap[x]; b=ap[y];
if (a>b)
{
dif=a;
a=b;
b=dif;
}
dif=b-a+1;
l=lg[dif];
sol=rmq[l][a];
q=dif-(1 << l);
if(niv[sol]>niv[rmq[l][a+q]])
sol=rmq[l][a+q];
return elr[sol];
}
void euler(int nod,int lev)
{
int i;
elr[++nr]=nod;
niv[nr]=lev;
ap[nod]=nr;
for (i=0;i<a[nod].size();i++)
{
euler(a[nod][i],lev+1);
elr[++nr]=nod;
niv[nr]=lev;
}
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d%d",&n,&m);
for (i=1;i<n;i++)
{
scanf("%d",&x);
a[x].push_back(i+1);
}
nr=0;
euler(1,0);
rmy();
for (i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}