Pagini recente » Cod sursa (job #2613914) | Cod sursa (job #1052260) | Cod sursa (job #836234) | Cod sursa (job #3033487) | Cod sursa (job #1464872)
#include <algorithm>
#include <vector>
#include <cstdio>
using namespace std ;
#define pb push_back
#define DIM 100005
#define LOG 20
int euler [ DIM << 1 ] ,l [ DIM << 1 ] , lg [ DIM << 1 ] , first_poz [ DIM ] ;
vector <int> Graph [DIM] ;
int rmq [ LOG ] [ DIM << 1 ] ;
int n , m , lg_euler ;
void read ()
{
int i , x ;
scanf ( "%d%d" , &n , &m ) ;
for ( i = 2 ; i <= n ; ++ i )
{
scanf ("%d",&x) ;
Graph [x].pb (i) ;
}
}
void df ( int nod , int lev ) // Parcurgere Euler
{
euler [ ++ lg_euler ] = nod ;
l [ lg_euler ] = lev ;
first_poz [nod] = lg_euler ;
for ( unsigned int i = 0 ; i < Graph [nod].size () ; ++ i )
{
df ( Graph [nod][i] , lev + 1 ) ;
euler [ ++ lg_euler ] = nod ;
l [ lg_euler ] = lev ;
}
}
void build_rmq ()
{
int i , j ;
for ( i = 2 ; i <= lg_euler ; ++ i ) // precalculez logaritmii..ca dupa sa fac in O (1)
lg[i] = lg[ i>>1 ] + 1 ;
for ( i = 1 ; i <= lg_euler ; ++ i )
rmq[0][i] = i ;
for ( i = 1 ; ( 1 << i ) < lg_euler ; ++ i )
for (j = 1 ; j <= lg_euler - ( 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) ) ] ;
}
void solve ()
{
int i , x , y , lung ;
for (i = 1 ; i <= m ; ++ i )
{
scanf ( "%d%d" , &x , &y ) ;
x = first_poz [x] ;
y = first_poz [y] ;
if ( x > y )
swap ( x , y ) ;
lung = lg[ y - x + 1 ] ;
if ( l [rmq[lung][x]] < l[rmq[lung][y - ( 1 << lung ) + 1]] )
printf ( "%d\n" , euler [rmq[lung][x]] ) ;
else
printf ( "%d\n" , euler [rmq[lung][y-( 1 << lung ) + 1]] );
}
}
int main ()
{
freopen ("lca.in","r",stdin);
freopen ("lca.out","w",stdout);
read ();
df (1,0);
build_rmq ();
solve ();
return 0;
}