Pagini recente » Cod sursa (job #397208) | Cod sursa (job #2481072) | Istoria paginii runda/ichb/clasament | Cod sursa (job #2435174) | Cod sursa (job #1050233)
/*
~Keep It Simple!~
*/
#include <stdio.h>
#include <list>
using namespace std;
#define maxn 100001
#define maxl 21
#define min(a,b) a<b ? a:b
int E[2*maxn],F[maxn],L[2*maxn],Rmq[maxn][maxl],Lg[maxn],n,m,k;
list<int> A[maxn];
void Euler(int node,int level)
{
E[++k] = node;
L[k] = level;
F[node] = k;
for(list<int>::iterator it = A[node].begin(); it!=A[node].end(); it++)
{
Euler(*it,level+1);
E[++k] = node;
L[k] = level;
}
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
int x;
scanf("%d %d",&n,&m);
for(int i=2; i<=n; i++)
{
scanf("%d",&x);
A[x].push_back(i);
}
Euler(1,0);
for(int i=2; i<=k; i++)
Lg[i] = Lg[i/2] + 1;
for(int i=1;i<=k;i++)
Rmq[i][0] = i;
for(int j = 1; (1<<j) < k; j++)
for(int i=1; i <= k - ( 1<<j ) ; i++)
{
if( L[Rmq[i][j-1]] > L[Rmq[ i + ( 1<<(j-1))][j-1]])
Rmq[i][j] = Rmq[ i + ( 1<<(j-1))][j-1];
else
Rmq[i][j] = Rmq[i][j-1];
}
int y;
for(int i=1; i<=m; i++)
{
scanf("%d %d",&x,&y);
x = F[x];
y = F[y];
if ( x > y ) { int aux = x; x=y; y = aux; }
int k = Lg[ y-x+1 ];
if( L[Rmq[x][k]] <= L[Rmq[y - (1<<k)+ 1][k]])
printf("%d\n",E[Rmq[x][k]]);
else
printf("%d\n",E[Rmq[y-(1<<k)+1][k]]);
}
}