Pagini recente » Cod sursa (job #343163) | Cod sursa (job #865904) | Cod sursa (job #784687) | Cod sursa (job #1227590) | Cod sursa (job #2605561)
#include <iostream>
#include <fstream>
#include <vector>
std::ifstream fin ( "lca.in" );
std::ofstream fout ( "lca.out" );
const int NMAX = 100000;
const int LGMAX = 20;
int father[1 + NMAX];
int level[1 + 2 * NMAX];
int v[1 + 2 * NMAX];
int first[1 + NMAX];
int l;
std::vector <int> edges[1 + NMAX];
void euler ( int node ) {
v[++l] = node;
first[node] = l;
level[node] = 1 + level[father[node]];
for ( int i = 0; i < edges[node].size(); ++i ) {
int newNode = edges[node][i];
euler ( newNode );
v[++l] = node;
}
}
class RMQ {
private :
short logs[1 + 2 * NMAX];
int rmq[LGMAX][2 * NMAX];
public :
void calculateLogs ( int N ) {
logs[1] = 0;
for ( int i = 2; i <= N; ++i )
logs[i] = 1 + logs[i / 2];
}
public :
void calculateRMQ ( int N ) {
for ( int i = 1; i <= N; ++i )
rmq[0][i] = i;
for ( int i = 1; i <= logs[N]; ++i ) {
for ( int j = 0; j <= N; ++j ) {
int st = rmq[i][j] = rmq[i - 1][j - ( 1 << ( i - 1 ) )];
int dr = rmq[i - 1][j];
if ( level[v[st]] > level[v[dr]] )
rmq[i][j] = dr;
else
rmq[i][j] = st;
}
}
}
public :
int minInterval ( int left, int right ) {
int l = logs[right - left + 1];
int st = rmq[l][left + ( 1 << l ) - 1];
int dr = rmq[l][right];
if ( level[v[st]] <= level[v[dr]] )
return v[st];
return v[dr];
}
};
RMQ rmq = RMQ();
int lca ( int x, int y ) {
int p = first[x];
int q = first[y];
if ( p > q )
std::swap ( p, q );
return rmq.minInterval ( p, q );
}
int main() {
int N, M;
fin >> N >> M;
for ( int i = 2; i <= N; ++i ) {
fin >> father[i];
edges[father[i]].push_back ( i );
}
euler ( 1 );
rmq.calculateLogs ( 2 * N - 1 );
rmq.calculateRMQ ( 2 * N - 1 );
for ( int i = 1; i <= M; ++i ) {
int x, y;
fin >> x >> y;
fout << lca ( x, y ) << '\n';
}
fin.close();
fout.close();
return 0;
}