Pagini recente » Cod sursa (job #3225787) | Cod sursa (job #2884336) | Cod sursa (job #957474) | Cod sursa (job #3185399) | Cod sursa (job #2823251)
#include <stdio.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
void swap( int& a, int& b ) {
a ^= b;
b ^= a;
a ^= b;
}
static inline int min( int a, int b ) {
return ( a <= b ? a : b );
}
static inline int max( int a, int b ) {
return ( a >= b ? a : b );
}
static inline int mod( int x ) {
return x < 0 ? -x : x;
}
#include <vector>
#define MAX 100005
std::vector<int> nod[ MAX ];
std::vector<int> el;
int lev[ MAX ], first[ MAX ];
int rmq[ MAX * 4 ][ 20 ];
int log_2[ MAX * 4 ];
int v[ MAX ];
int n, q;
void dfs( int x ) {
el.push_back( x );
first[ x ] = el.size() - 1;
lev[ x ] = lev[ v[ x ] ] + 1;
for( auto next: nod[ x ] )
if( next != v[ x ] ) {
dfs( next );
el.push_back( x );
}
}
int lca( int x, int y ) {
int a = first[ x ];
int b = first[ y ];
if( a > b )
swap( a, b );
int lg = log_2[ b - a + 1 ];
int rez = rmq[ a ][ lg ];
if( lev[ rmq[ b - ( 1 << lg ) + 1 ][ lg ] ] < lev[ rez ] )
rez = rmq[ b - ( 1 << lg ) + 1 ][ lg ];
return rez;
}
int main()
{
FILE *fin = fopen( "lca.in", "r" );
fscanf( fin, "%d%d", &n, &q );
for( int i = 2; i <= n; i++ ) {
fscanf( fin, "%d", &v[ i ] );
nod[ i ].push_back( v[ i ] );
nod[ v[ i ] ].push_back( i );
}
dfs( 1 );
log_2[ 1 ] = 0;
int l = el.size();
for( int i = 2; i <= l; i++ )
log_2[ i ] = log_2[ i / 2 ] + 1;
for( int i = 0; i < l; i++ )
rmq[ i ][ 0 ] = el[ i ];
for( int j = 1; j <= log_2[ l ]; j++ )
for( int i = 0; i + ( 1 << j ) <= l; i++ ) {
rmq[ i ][ j ] = rmq[ i ][ j - 1 ];
if( lev[ rmq[ i + ( 1 << ( j - 1 ) ) ][ j - 1 ] ] < lev[ rmq[ i ][ j ] ] )
rmq[ i ][ j ] = rmq[ i + ( 1 << ( j - 1 ) ) ][ j - 1 ];
}
int x, y;
FILE *fout = fopen( "lca.out", "w" );
while( q-- ) {
fscanf( fin, "%d%d", &x, &y );
fprintf( fout, "%d\n", lca( x, y ) );
}
fclose( fin );
fclose( fout );
return 0;
}