Pagini recente » Cod sursa (job #1133710) | Cod sursa (job #216332) | Cod sursa (job #2804222) | Cod sursa (job #53304) | Cod sursa (job #1708713)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#define NMAX 100009
#define LOGMAX 30
using namespace std;
int N, Q, level[ NMAX ], euler[2 * NMAX], fst[ NMAX ], lg[ NMAX ], lgmax, rmq[LOGMAX][NMAX];
vector<int> G[ NMAX ];
void DFS(int node, int l) {
level[ node ] = l;
euler[ ++euler[0] ] = node;
fst[ node ] = euler[ 0 ];
for (vector<int>::iterator it = G[node].begin(); it != G[node].end(); ++it) {
DFS( *it, l + 1);
euler[ ++euler[0] ] = node;
}
}
void buildRMQ() {
for (int i = 1; i <= euler[ 0 ]; ++i) {
lg [ i ] = lg[ i / 2 ] + 1;
}
for (int i = 1; i <= euler[0]; ++i) {
rmq[ 0 ][ i ] = euler[ i ];
}
lgmax = log2( euler[ 0 ] );
for (int k = 1; k <= lgmax; ++k) {
int imax = euler[ 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) {
int st = fst[x], dr = fst[y];
if (st > dr) {
swap(st, dr);
}
int k = lg[ dr - st + 1];
x = rmq[ k - 1][ st ], y = rmq[ k - 1 ][ 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;
}