Pagini recente » Cod sursa (job #2604880) | Cod sursa (job #577481) | Cod sursa (job #2732712) | Cod sursa (job #2732694) | Cod sursa (job #2310558)
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <deque>
#include <queue>
#include <iomanip>
#include <algorithm>
#define pb push_back
#define sz size()
using namespace std ;
const int NR = 100001 ;
const int oo = 1 << 30 ;
ifstream f ("lca.in") ;
ofstream g ("lca.out") ;
vector < int > v [ NR ] ;
vector < bool > viz ( NR , false ) ;
vector < int > euler ( 2 * NR ) ;
vector < int > level ( NR , oo ) ;
vector < int > frst ( NR ) ;
int n , q , cnt ;
void input ()
{
f >> n >> q ;
for ( size_t i = 2 ; i <= n ; ++ i )
{
int x ; f >> x ; v [ i ].pb( x ) ; v [ x ].pb( i ) ;
}
level [ 1 ] = 0 ;
}
void dfs_euler ( int nod )
{
viz [ nod ] = true ;
frst [ nod ] = cnt + 1 ;
for ( size_t i = 0 ; i < v [ nod ].sz ; ++ i )
if ( !viz [ v [ nod ][ i ] ] )
{
euler [ ++ cnt ] = nod ;
level [ v [ nod ][ i ] ] = min ( level [ nod ] + 1 , level [ v [ nod ][ i ] ] ) ;
dfs_euler ( v [ nod ][ i ] ) ;
}
euler [ ++ cnt ] = nod ;
}
int a [ 2 * NR ][ 20 ] ;
int lg [ 2 * NR ] ;
void rmq ( )
{
for ( size_t i = 1 ; i <= cnt ; ++ i ) a [ i ][ 0 ] = i ;
for ( size_t j = 1 ; ( 1 << j ) <= cnt ; ++ j )
for ( size_t 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 ][ j - 1 ] ;
else
a [ i ][ j ] = a [ i + ( 1 << ( j - 1 ) ) ][ j - 1 ] ;
for ( size_t i = 2 ; i <= cnt ; i <<= 1 ) lg [ i ] = 1 ;
for ( size_t i = 3 ; i <= cnt ; ++ i ) lg [ i ] += lg [ i - 1 ] ;
}
void task ( int x , int y )
{
int st = frst [ x ] ;
int dr = frst [ y ] ;
if ( st > dr ) swap ( st , dr ) ;
int i = dr - st + 1 ;
if ( level [ euler [ a[ st ][ lg [ i ] ] ] ] > level [ euler [ a [ dr - ( 1 << ( lg [ i ] ) ) + 1 ][ lg [ i ] ] ] ] )
g << euler [ a [ dr - ( 1 << ( lg [ i ] ) ) + 1 ][ lg [ i ] ] ] << "\n" ;
else
g << euler [ a[ st ][ lg [ i ] ] ] << "\n" ;
}
void solve_tasks ()
{
int x, y ;
for( size_t i = 0 ; i < q ; ++ i )
{
f >> x >> y ;
task ( x , y ) ;
}
}
int main ()
{
input() ;
dfs_euler ( 1 ) ;
rmq() ;
solve_tasks() ;
return 0 ;
}