Pagini recente » Cod sursa (job #1144458) | Cod sursa (job #1958263) | Cod sursa (job #1045702) | Cod sursa (job #518958) | Cod sursa (job #605968)
Cod sursa(job #605968)
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<vector>
#include<deque>
#include<set>
#define NMAX 100010
#define logN 20
using namespace std;
vector< int > G[NMAX];
int E[NMAX<<1],P[NMAX];
int RMQ[logN][NMAX<<2];
int L[NMAX<<1];
bool viz[NMAX];
int N;
void euler( int nod,int level )
{
viz[nod]=1;
E[ ++E[0] ]=nod;
L[ E[0] ]=level;
P[ nod ]=E[0];
int i,v;
for(i=0; i<(signed)G[nod].size(); ++i)
{
v=G[nod][i];
if( !viz[v] )
{
euler(v,level+1);
E[++E[0]]=nod;
L[E[0]]=level;
}
}
}
int PW2[NMAX<<1];
void pw2()
{
int i;
for(i=2; i<(NMAX<<1); ++i)
PW2[i]=PW2[i>>1]+1;
}
void rmq()
{
int i,j;
int N=E[0];
for(i=1; i<=N; ++i)
RMQ[0][i]=i;
for(i=1; (1<<i)<N; ++i)
{
for(j=1; j<=N-(1<<i); ++j)
{
if( L[RMQ[i-1][j]]<L[RMQ[i-1][j+(1<<(i-1))]])
RMQ[i][j]=RMQ[i-1][j];
else
RMQ[i][j]=RMQ[i-1][j+(1<<(i-1))];
}
}
}
int query( int nod1, int nod2 )
{
int p1=P[nod1];
int p2=P[nod2];
if( p2<p1 )
{
p1^=p2;p2^=p1;p1^=p2;
}
int diff=p2-p1+1;
int d=PW2[diff];
int sh=diff-(1<<d);
if( L[ RMQ[d][p1] ] < L[ RMQ[d][p1+sh] ] )
{
return E[ RMQ[d][p1] ];
}
else
{
return E[ RMQ[d][ p1+sh ] ];
}
}
void DF(int nod)
{
viz[nod]=0;
int i,v;
for(i=0; i<(signed)G[nod].size(); ++i)
{
v=G[nod][i];
if( L[P[v]]>L[P[nod]] && viz[v] )
DF(v);
}
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
int N,M;
scanf("%d%d\n",&N,&M);
int i,a1;
for(i=2; i<=N; ++i)
{
scanf("%d",&a1);
G[a1].push_back(i);
G[i].push_back(a1);
}
pw2();
euler(1,1);
rmq();
int a2;
for(i=1; i<=M; ++i)
{
scanf("%d%d\n",&a1,&a2);
printf("%d\n",query(a1,a2));
}
return 0;
}