Pagini recente » Cod sursa (job #450083) | Cod sursa (job #3196635) | Cod sursa (job #145103) | Cod sursa (job #1073987) | Cod sursa (job #2598858)
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int DP[17][100005], depth[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 = 0; i <= 16 && n; ++i)
if (n & (1<<i)) {
n ^= (1<<i);
k = DP[i][k];
}
return k;
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
ios::sync_with_stdio(false);
fin.tie(0);
fout.tie(0);
int N, M;
fin >> N >> M;
for (int i = 2; i <= N; ++i) {
int x;
fin >> x;
Graph[x].emplace_back(i);
DP[0][i] = x; // 2^0th ancestor of i is x
}
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;
fin >> a >> b;
if (depth[a] < depth[b])
swap(a, b);
int difference = depth[a] - depth[b];
a = nthAncestor(a, difference);
if (a == b) {
fout << a << "\n";
continue;
}
for (int k = 16; k >= 0; --k)
if (DP[k][a] != DP[k][b]) {
a = DP[k][a];
b = DP[k][b];
}
fout << DP[0][a] << "\n";
}
}