Pagini recente » Cod sursa (job #164506) | Cod sursa (job #534033) | Cod sursa (job #867525) | Cod sursa (job #1135616) | Cod sursa (job #1749866)
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define NMAX 100005
#define lgNNMAX 20
vector < int > v[ NMAX ];
int lg[ NMAX * 2 ];
int euler[ NMAX * 2 ];
int deep[ NMAX * 2 ];
int first[ NMAX * 2 ];
int rmq[ lgNNMAX ][ NMAX * 2 ];
int indi;
void computeLCA( int nod, int niv );
void computeRMQ();
int solveLCA( int x, int y );
int minim( int a, int b );
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
int n, m, i, j, s, t, d, k, x, y;
scanf("%d%d",&n,&m);
for( i = 2; i <= n; ++i ){
scanf("%d",&x);
v[ x ].push_back( i );
}
computeLCA( 1, 0 );
//for( i = 1; i <= indi; ++i ) printf("%d ",deep[ i ]);
computeRMQ( );
while( m-- ){
scanf("%d%d",&x,&y);
printf("%d\n",solveLCA( x, y ));
}
return 0;
}
int minim( int a, int b ){
if( a < b ) return a;
return b;
}
int solveLCA( int x, int y ){
x = first[ x ];
y = first[ y ];
if( x > y ) swap( x, y );
int l = y - x + 1;
int p = lg[ l ];
//printf("-> %d %d\n",rmq[ p ][ x ], deep[ rmq[ p ][ x + ( 1 << p ) ] ] );
int mina = rmq[ p ][ y + 1 - ( 1 << p ) ] ;
if( deep[ rmq[p][x] ] < deep[ mina ] ) mina = rmq[p][x];
return euler[ mina ];
}
void computeRMQ(){
int i, j, rmq1;
rmq[ 0 ][ 1 ] = 1;
for( i = 2; i <= indi; ++i ){
lg[ i ] = lg[ i / 2 ] + 1;
rmq[ 0 ][ i ] = i;
}
for( i = 1; ( 1 << i ) < indi; ++i ){
for( j = 1; j + ( 1 << i ) <= indi; ++j ){
rmq[ i ][ j ] = rmq[ i - 1 ][ j ];
int p = 1 << ( i - 1 );
rmq1 = rmq[ i - 1 ][ j + p ];
if( deep[ rmq[ i ][ j ] ] > deep[ rmq1 ] ) rmq[ i ][ j ] = rmq1;
}
}
}
void computeLCA( int nod, int niv ){
int i;
euler[ ++indi ] = nod;
deep[ indi ] = niv;
first[ nod ] = indi;
for( i = 0; i < v[ nod ].size(); ++i ){
computeLCA( v[ nod ][ i ], niv + 1 );
euler[ ++indi ] = nod;
deep[ indi ] = niv;
}
}