Pagini recente » Cod sursa (job #1824265) | Cod sursa (job #32158) | Cod sursa (job #1993380) | Cod sursa (job #1660792) | Cod sursa (job #2590798)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin( "lca.in" );
ofstream fout( "lca.out" );
const int NMAX = 1e5;
vector <int> son[NMAX + 1];
vector <int> euler;
vector <int> level;
int first_apparence[NMAX + 1];
int rmq[20][2 * NMAX];
int log[2 * NMAX];
void read_tree( int n ) {
for ( int i = 1; i < n; i ++ ) {
int node;
fin >> node;
son[node].push_back( i + 1 );
}
}
void dfs( int node, int current ) {
euler.push_back( node );
level.push_back( current );
for ( int x : son[node] ) {
dfs( x, current + 1 );
euler.push_back( node );
level.push_back( current );
}
}
void calc_apparances( int n ) {
int i;
for ( i = 1; i <= n; i ++ )
first_apparence[i] = 2 * n + 1;
i = 0;
for ( auto& x : euler ) {
first_apparence[x] = min( first_apparence[x], i );
i ++;
}
}
void calc_log() {
for ( int i = 2; i < 2 * NMAX; i ++ )
log[i] = log[i / 2] + 1;
}
void calc_rmq() {
calc_log();
for ( int i = 0; i < level.size(); i ++ ) {
rmq[0][i] = i;
}
for ( int l = 1; ( 1 << l ) <= level.size(); l ++ ) {
for ( int i = 0; i <= level.size() - ( 1 << l ); i ++ ) {
if ( level[rmq[l - 1][i]] <= level[rmq[l - 1][i + ( 1 << ( l - 1 ) )]] ) {
rmq[l][i] = rmq[l - 1][i];
} else {
rmq[l][i] = rmq[l - 1][i + ( 1 << ( l - 1 ) )];
}
}
}
}
int query( int l, int r ) {
if ( l > r )
swap( l, r );
int lg = log[r - l + 1];
if ( level[rmq[lg][l]] < level[rmq[lg][r - ( 1 << lg ) + 1]] )
return euler[level[rmq[lg][l]]];
else
return euler[rmq[lg][r - ( 1 << lg ) + 1]];
}
int main() {
int n, m, i, a, b;
fin >> n >> m;
read_tree( n );
dfs( 1, 0 );
calc_apparances( n );
calc_rmq();
for ( i = 0; i < m; i ++ ) {
fin >> a >> b;
fout << query( first_apparence[a], first_apparence[b] ) << '\n';
}
return 0;
}