Pagini recente » Cod sursa (job #2758496) | Cod sursa (job #1109081) | Cod sursa (job #1368176) | Cod sursa (job #1320715) | Cod sursa (job #2598926)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int DP[17][100005], depth[100005], Log2[100005];
vector<int> Graph[100005];
void calculateDepth(int k, int d)
{
depth[k] = d;
for (auto v: Graph[k])
calculateDepth(v, d + 1);
}
int nthAncestor(int k, int n)
{
for (int i = Log2[n]; i >=0; --i)
if (n & (1<<i))
k = DP[i][k];
return k;
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int N, M;
scanf("%d%d", &N, &M);
Log2[1] = 0;
for (int i = 2; i <= N; ++i) {
int x;
scanf("%d", &x);
Graph[x].emplace_back(i);
DP[0][i] = x; // 2^0th ancestor of i is x
Log2[i] = Log2[i/2] + 1;
}
DP[0][1] = 1;
for (int i = 1; i <= 16; ++i)
for (int j = 1; j <= N; ++j) // 2^i th ancestor of j is the 2^(i-1)th ancestor of the 2^(i-1)th ancestor of j
DP[i][j] = DP[i-1][DP[i-1][j]];
calculateDepth(1, 0);
for (int i = 1; i <= M; ++i) {
int a, b;
scanf("%d%d", &a, &b);
if (depth[a] < depth[b])
swap(a, b);
int difference = depth[a] - depth[b];
a = nthAncestor(a, difference);
if (a == b) {
printf("%d\n", a);
continue;
}
for (int k = Log2[depth[a]]; k >= 0; --k)
if (DP[k][a] != DP[k][b]) {
a = DP[k][a];
b = DP[k][b];
}
printf("%d\n", DP[0][a]);
}
}