Pagini recente » Cod sursa (job #2221241) | Cod sursa (job #28046) | Cod sursa (job #173153) | Cod sursa (job #2243076) | Cod sursa (job #1569322)
#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 depth[1 + MAX_N];
int father[1 + LOG_MAX_N][1 + MAX_N];
queue<int> bfsQ;
void climb(int &node, int level) {
int i;
for (i = 0; level > 0; i++, level >>= 1) {
if ((level & 1) > 0) {
node = father[i][node];
}
}
}
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 = 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 = LOG_MAX_N; 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;
}