Pagini recente » Cod sursa (job #987493) | Cod sursa (job #532810) | Cod sursa (job #1213663) | Cod sursa (job #1732155) | Cod sursa (job #1752831)
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define NMAX 100005
vector < int > v[ NMAX ];
int indi;
int euler[ NMAX * 2 ], nivele[ NMAX * 2 ], first[ NMAX ];
int rmq[ 20 ][ NMAX * 2 ], lg[ NMAX * 2 ];
void computeRMQ( );
int LCA( int x, int y );
void computeLCA( int nod, int niv );
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
int n, m, i, j, x, y, q;
scanf("%d%d",&n,&m);
for( i = 2; i <= n; ++i ){
scanf("%d",&x);
v[ x ].push_back( i );
}
computeLCA( 1, 0 );
computeRMQ( );
while( m-- ){
scanf("%d%d",&x,&y);
printf("%d\n",LCA( x, y ));
}
return 0;
}
void computeRMQ( ){
int i, j, k;
for( i = 2; i <= indi; ++i ) lg[ i ] = lg[ i / 2 ] + 1;
for( i = 1; i <= indi; ++i ) rmq[ 0 ][ i ] = i;
for( i = 1; ( 1 << i ) < indi; ++i ){
k = ( 1 << i );
for( j = 1; j + k <= indi; ++j ){
rmq[ i ][ j ] = rmq[ i - 1 ][ j + k / 2 ];
if( nivele[ rmq[ i - 1 ][ j ] ] < nivele[ rmq[ i ][ j ] ] )
rmq[ i ][ j ] = rmq[ i - 1 ][ j ];
}
}
}
int LCA( int x, int y ){
int a, b, dif;
x = first[ x ]; y = first[ y ];
if( x > y ) swap( x, y );
dif = lg[ y - x + 1 ];
a = rmq[ dif ][ x ];
b = rmq[ dif ][ y + 1 - ( 1 << dif ) ];
if( nivele[ b ] < nivele[ a ] ) a = b;
return euler[ a ];
}
void computeLCA( int nod, int niv ){
vector < int > :: iterator it;
euler[ ++indi ] = nod; nivele[ indi ] = niv; first[ nod ] = indi;
for( it = v[ nod ].begin(); it != v[ nod ].end(); ++it ){
computeLCA( *it, niv + 1 );
euler[ ++indi ] = nod; nivele[ indi ] = niv;
}
}