Pagini recente » Cod sursa (job #2395012) | Cod sursa (job #124102) | Cod sursa (job #2928035) | Cod sursa (job #2447615) | Cod sursa (job #2768136)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
const int NMAX = 1e5;
const int MMAX = 2e6;
const int MAX_LOG = 18;
const int ROOT = 1;
vector<int> graf[1 + NMAX];
int height[2 * NMAX], node[2 * NMAX];
int index[1 + NMAX];
int step = 1;
void euler_tour ( int root, int root_height ) {
///cout << root << " ";
height[step] = root_height;
node[step] = root;
index[root] = step ++;
for ( auto adj_node : graf[root] ) {
euler_tour ( adj_node, root_height + 1 );
///cout << root << " ";
height[step] = root_height;
node[step] = root;
index[root] = step ++;
}
}
int RMQ[2 * NMAX + 1][1 + MAX_LOG];
int LOG_Table[2 * NMAX + 1];
void generate_LogTable () {
LOG_Table[1] = 0;
for ( int this_index = 2; this_index <= 2 * NMAX + 1; this_index ++ )
LOG_Table[this_index] = LOG_Table[this_index / 2] + 1;
}
void generate_RMQ () {
step --;
for ( int i = 1; i <= step; i ++ )
RMQ[i][0] = i;
for ( int jump = 1; ( 1 << jump ) <= step; jump ++ ) {
for ( int i = 1; i + ( 1 << jump ) - 1 <= step; i ++ ) {
int mid_point = i + ( 1 << ( jump - 1 ) );
int first_half = RMQ[i][jump - 1]; int second_half = RMQ[mid_point][jump - 1];
if ( height[first_half] < height[second_half] )
RMQ[i][jump] = first_half;
else
RMQ[i][jump] = second_half;
}
}
}
int query_RMQ ( int first_node, int second_node ) {
int first_index = index[first_node];
int second_index = index[second_node];
if ( first_index > second_index )
swap ( first_index, second_index );
int interval_length = second_index - first_index + 1;
int rmq_log = LOG_Table[interval_length];
int first_half = RMQ[first_index][rmq_log];
int second_half = RMQ[second_index - ( 1 << rmq_log ) + 1][rmq_log];
if ( height[first_half] < height[second_half] )
return node[first_half];
return node[second_half];
}
ifstream fin ( "lca.in" );
ofstream fout ( "lca.out" );
int main()
{
int n, q; fin >> n >> q;
for ( int i = 1; i < n; i ++ ) {
int node; fin >> node;
graf[node].push_back ( i + 1 );
}
euler_tour ( ROOT, 0 );
generate_LogTable (); generate_RMQ ();
for ( int i = 1; i <= q; i ++ ) {
int first_node, second_node; fin >> first_node >> second_node;
fout << query_RMQ ( first_node, second_node ) << "\n";
}
return 0;
}