Pagini recente » Cod sursa (job #407715) | Borderou de evaluare (job #3126189) | Cod sursa (job #1569328)
#include <stdio.h>
#include <assert.h>
#include <vector>
#include <queue>
using std::vector;
using std::queue;
const int MAX_N = 100000;
const int LOG_MAX_N = 17;
int N, M;
vector<int> sons[1 + MAX_N];
int power[(1 << LOG_MAX_N) + 1];
int depth[1 + MAX_N];
int father[1 + LOG_MAX_N][1 + MAX_N];
queue<int> bfsQ;
void climb(int &node, int level) {
while (level > 0) {
node = father[power[level & (-level)]][node];
level &= level - 1;
}
}
int main() {
int i, j;
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d %d", &N, &M);
for (i = 2; i <= N; i++) {
scanf("%d", &father[0][i]);
sons[father[0][i]].push_back(i);
}
for (i = 1; i <= LOG_MAX_N; i++) {
for (j = 1; j <= N; j++) {
father[i][j] = father[i - 1][father[i - 1][j]];
}
}
bfsQ.push(1);
depth[1] = 1;
while (!bfsQ.empty()) {
int node = bfsQ.front();
bfsQ.pop();
for(int son : sons[node]) {
bfsQ.push(son);
depth[son] = depth[node] + 1;
}
}
for (i = 0; i <= LOG_MAX_N; i++) {
power[1 << i] = i;
}
for (i = 0; i <= N; i++) {
if (power[i] == 0) {
power[i] = power[i - 1];
}
}
for (i = 1; i <= M; i++) {
int a, b;
int lca;
scanf("%d %d", &a, &b);
int dif = depth[a] - depth[b];
if (dif < 0) {
climb(b, -dif);
} else {
climb(a, dif);
}
assert(depth[a] == depth[b]);
if (a == b) {
lca = a;
} else {
for (j = power[depth[a]]; j >= 0; j--) {
if (father[j][a] != father[j][b]) {
a = father[j][a];
b = father[j][b];
}
}
lca = father[0][a];
}
printf("%d\n", lca);
}
return 0;
}