Pagini recente » Cod sursa (job #2525525) | Cod sursa (job #891433) | Cod sursa (job #1878721) | Cod sursa (job #2230859) | Cod sursa (job #2310480)
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#define pb push_back
#define sz size()
using namespace std ;
ifstream f ( "lca.in" ) ;
ofstream g ( "lca.out" ) ;
const int NR = 200001 ;
const int oo = (1 << 18 ) ;
vector < int > v [ NR ] ;
vector < bool > viz ( NR , false ) ;
vector < int > euler ( NR , 0 ) ;
vector < int > level ( NR , 0 ) ;
vector < int > primap ( NR , oo ) ;
int n , m , cnt ;
void dfs ( int nod )
{
viz [ nod ] = true ;
for ( size_t i = 0 ; i < v [ nod ].sz ; ++ i )
if( !viz [ v[ nod ][ i ] ] )
{
euler [ ++ cnt ] = nod ;
primap [ nod ] = min ( cnt , primap [ nod ] ) ;
level [ v [ nod ][ i ] ] = level [ nod ] + 1 ;
dfs ( v [ nod ][ i ] ) ;
}
euler [ ++ cnt ] = nod ;
primap [ nod ] = min ( cnt , primap [ nod ] ) ;
}
int main ()
{
f >> n >> m ;
int i , j ;
for ( i = 2 ; i <= n ; ++ i ) { int a ; f >> a ; v [ a ].pb (i) ; v [ i ].pb (a) ; }
level [ 1 ] = 1 ;
dfs (1) ;
//for ( int i = 1 ; i <= cnt ; ++ i ) g << euler [ i ] << " " ;
//g << "\n" ;
//for ( int i = 1 ; i <= n ; ++ i ) g << level [ i ] << " " ;
int a [ cnt + 1 ][ 20 ] ;
for ( i = 1 ; i <= cnt ; ++ i ) a [ i ][ 0 ] = i ;
//g << "\n" ;
//for ( i = 1 ; i <= n ; ++ i ) g << primap [ i ] << ' ' ;
//g <<"\n\n";
for ( j = 1 ; ( 1 << j ) <= cnt ; ++ j )
for ( i = 1 ; i + ( 1 << j ) <= cnt ; ++ i )
if ( level [ euler [ a [ i ][ j - 1 ] ] ] > level [ euler [ a [ i + ( 1 << ( j - 1 ) ) ][ j - 1 ] ] ] )
a [ i ][ j ] = a [ i + ( 1 << ( j - 1 ) ) ][ j - 1 ] ;
else
a [ i ][ j ] = a [ i ][ j - 1 ] ;
int lg [ n + 1 ] = {0} ;
for ( i = 2 ; i <= n ; i <<= 1 ) lg [ i ] = 1 ;
for ( i = 3 ; i <= n ; ++ i ) lg [ i ] += lg [ i - 1 ] ;
while ( m -- )
{
int st , dr ; f >> st >> dr ;
st = primap [ st ] ;
dr = primap [ dr ] ;
if ( dr < st ) swap ( st , dr ) ;
//g << st << " " << dr << "\n" ;
i = lg [ abs ( dr - st ) + 1 ] ;
if ( level [ euler [ a [ st ][ i ] ] ] > level [ euler [ a [ dr - ( 1 << i ) + 1 ][ i ] ] ] )
g << euler [ a [ dr - ( 1 << i ) + 1 ][ i ] ] << "\n" ;
else
g << euler [ a [ st ][ i ] ] << "\n" ;
}
return 0 ;
}