Pagini recente » Cod sursa (job #3286113) | Cod sursa (job #1965749) | Cod sursa (job #2884469) | Cod sursa (job #1928636) | Cod sursa (job #1708717)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cassert>
#define NMAX 100025
#define LOGMAX 40
using namespace std;
int N, Q, level[ NMAX ], e[2 * NMAX], fst[ NMAX ], lg[ 2 * NMAX ], lgmax, rmq[LOGMAX][2 * NMAX];
bitset<NMAX> viz;
vector<int> G[ NMAX ];
void DFS(int node, int l) {
viz[ node ] = 1;
level[ node ] = l;
e[ ++e[0] ] = node;
fst[ node ] = e[ 0 ];
for (vector<int>::iterator it = G[node].begin(); it != G[node].end(); ++it) {
if (!viz[ *it ]) {
DFS( *it, l + 1);
e[ ++e[0] ] = node;
}
}
}
void buildRMQ() {
for (int i = 2; i <= e[ 0 ]; ++i) {
lg [ i ] = lg[ i / 2 ] + 1;
}
for (int i = 1; i <= e[0]; ++i) {
rmq[ 0 ][ i ] = e[ i ];
}
lgmax = log2( e[ 0 ] );
for (int k = 1; k <= lgmax; ++k) {
int imax = e[ 0 ] - (1 << k) + 1;
for (int i = 1; i <= imax; ++i) {
int x = rmq[ k - 1][ i ], y = rmq[ k - 1][ i + (1 << (k-1))];
rmq[ k ][ i ] = (level[ x ] < level[ y ] ? x : y);
}
}
}
int lca(int x, int y) {
if (x == y) {
return x;
}
int st = fst[ x ], dr = fst[ y ];
if (st > dr) {
swap(st, dr);
}
int k = lg[ dr - st + 1 ];
x = rmq[ k ][ st ];
y = rmq[ k ][ dr - (1 << k ) + 1 ];
return (level[ x ] < level[ y ] ? x : y);
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &N, &Q);
for (int i = 2; i <= N; ++i) {
int x;
scanf("%d", &x);
G[ x ].push_back( i );
}
DFS(1, 1);
buildRMQ();
while (Q--) {
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", lca(x, y));
}
return 0;
}