Pagini recente » Cod sursa (job #1554325) | Cod sursa (job #1733445) | Cod sursa (job #1223074) | Cod sursa (job #1741866) | Cod sursa (job #1216820)
#include <fstream>
#include <vector>
#define rint register int
#define pb push_back
const char IN [ ] = "lca.in" ;
const char OUT [ ] = "lca.out" ;
const int MAX = 100014;
const int LOGMAX = 22;
using namespace std;
ifstream fin ( IN ) ;
ofstream fout ( OUT ) ;
struct euler {
int nivel , nod ;
};
euler q [ MAX << 1 ] ;
vector < int > gr [ MAX ] ;
int now , first [ MAX ] , R [ LOGMAX ] [ MAX ] , log [ MAX ] ;
void dfs ( int nod , int lvl )
{
++ now ;
q [ now ].nivel = lvl ;
q [ now ].nod = nod ;
first [ nod ] = now ;
for ( auto x : gr [ nod ] )
{
dfs ( x , lvl + 1 ) ;
++ now ;
q [ now ].nivel = lvl ;
q [ now ].nod = nod ;
}
}
void RMQ ( int n )
{
log [ 1 ] = 0 ;
for ( rint i = 2 ; i <= n ; ++ i )
log [ i ] = log [ i >> 1 ] + 1 ;
for ( rint i = 1 ; i <= n ; ++ i )
R [ 0 ] [ i ] = i ;
for ( rint i = 1 ; (1 << i) <= n ; ++ i )
for ( rint j = 1 ; j <= n - (1<<i) + 1 ; ++ j )
{
int l = 1 << ( i - 1 ) ;
R [ i ] [ j ] = R [ i - 1 ] [ j ] ;
if ( q [ R [ i ] [ j ] ].nivel > q [ R [ i - 1 ][ j + l ] ].nivel )
R [ i ] [ j ] = R [ i - 1 ][ j + l ] ;
}
}
int lca ( int x , int y )
{
int a = first [ x ] ;
int b = first [ y ] ;
if ( a > b )
swap ( a , b ) ;
int diff = b - a + 1 ;
int lg = log [ diff ] ;
int sol = R [ lg ] [ a ] ;
int sh = diff - (1 << lg) ;
if ( q [ sol ].nivel > q[ R [ lg ] [ a + sh ] ].nivel )
sol = R [ lg ] [ a + sh ];
return q [ sol ].nod ;
}
int main( )
{
int n , m ;
fin >> n >> m ;
for ( rint i = 2 ; i <= n ; ++ i )
{
int x ;
fin >> x;
gr [ x ] . pb( i ) ;
}
dfs ( 1 , 0 ) ;
RMQ ( now ) ;
while ( m -- )
{
int x, y ;
fin >> x >> y ;
fout << lca ( x , y ) << '\n' ;
}
return 0;
}