Pagini recente » Cod sursa (job #2345819) | Cod sursa (job #2292297) | Cod sursa (job #1210937) | Cod sursa (job #1782721) | Cod sursa (job #1773765)
#include <cstdio>
#include <cmath>
#include <vector>
#define N 100005
using namespace std;
int niv[N<<1],euler[N<<1],viz[N],lg[N<<1],rmq[25][N],n,m,k;
vector <int> g[N];
void read()
{
int i,x;
scanf("%d%d",&n,&m);
for (i=2;i<=n;i++)
{
scanf("%d",&x);
g[x].push_back(i);
}
}
void dfs(int nod,int nivel)
{
vector <int>::iterator it;
euler[++k]=nod;
niv[k]=nivel;
if (!viz[nod]) viz[nod]=k;
for (it=g[nod].begin();it!=g[nod].end();it++)
{
dfs(*it,nivel+1);
euler[++k]=nod;
niv[k]=nivel;
}
}
void Rmq()
{
int i,j,l;
for(i=2; i<=k; ++i)
lg[i]=lg[i >> 1]+1;
for (i=1;i<=k;i++)
rmq[0][i]=i;
for (i=1;(1<<i)<k;++i)
for (j=1;j<=k-(1<<i);++j)
{
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=viz[x];b=viz[y];
if (a>b) swap(a,b);
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 euler[sol];
}
int main()
{
int i,x,y;
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
read();
dfs(1,0);
Rmq();
for (i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
}