Pagini recente » Istoria paginii utilizator/marina.lecu | Istoria paginii utilizator/pitcovicinatalia | Profil Ivan_22 | Monitorul de evaluare | Cod sursa (job #886979)
Cod sursa(job #886979)
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
#define max_n 100005
#define fi first
#define se second
#define FORIT( it,v ) for( typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it )
pair<int,int> Parcurgere[ 2*max_n ], Rmk[ 2*max_n ][ 20 ];
bool Viz[ max_n ];
int First[ max_n ], Log[ 2*max_n ];
int a,b,d,n,m,q,f,i;
vector<int> Vertex[ max_n ];
void euler( int nod, int level ){
Viz[ nod ] = 1;
Parcurgere[ ++m ] = make_pair( level, nod );
First[ nod ] = m;
FORIT( it, Vertex[ nod ] ){
if( !Viz[ *it ] ){
euler( *it, level+1 );
Parcurgere[ ++m ] = make_pair( level, nod );
}
}
}
pair<int,int> min( pair<int,int> a, pair<int,int> b ){
if ( a.fi < b.fi )
return a;
return b;
}
void make_rmk(){
int i,l;
Log[ 0 ] = 0;
Log[ 1 ] = 0;
for( i=2; i<=m; ++i ){
Log[ i ] = Log[ i>>1 ] + 1;
}
for( i=1; i<=m; ++i ){
Rmk[ i ][ 0 ] = Parcurgere[ i ];
}
for( l=1; (1<<l) <=m; ++l ){
for( i=1; i+(1<<l)-1 <=m; ++i ){
Rmk[ i ][ l ] = min( Rmk[ i ][ l-1 ], Rmk[ i+(1<<(l-1)) ][ l-1 ] );
}
}
return ;
}
int main(){
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d %d", &n, &q );
for ( i=2; i<=n; ++i ){
scanf("%d", &a );
Vertex[ a ].push_back( i );
}
euler( 1, 1 );
make_rmk();
for( ; q; --q ){
scanf("%d %d", &a, &b );
a = First[ a ];
b = First[ b ];
if ( a > b )
swap( a,b );
d = b-a+1;
i = Log[ d ];
printf("%d\n", min( Rmk[ a ][ i ], Rmk[ b-(1<<i)+1 ][ i ] ).se );
}
return 0;
}