Pagini recente » Cod sursa (job #1171185) | Cod sursa (job #2308476) | Cod sursa (job #1609356) | Cod sursa (job #1973213) | Cod sursa (job #2729743)
#include <iostream>
#include <fstream>
#include <cassert>
const int LOG = 16;
const int NMAX = 1e5;
int t[1 + NMAX][1 + LOG];
int level[1 + NMAX];
inline int ancestor(int node, int depth) {
int e = 0;
while (depth) {
if (depth & 1)
node = t[node][e];
++e;
depth >>= 1;
}
return node;
}
int calc_level(int i) {
if (level[t[i][0]] != 0)
level[i] = 1 + level[t[i][0]];
else
level[i] = 1 + calc_level(t[i][0]);
return level[i];
}
int main() {
std::ifstream in("lca.in");
std::ofstream out("lca.out");
int n, m;
in >> n >> m;
for (int i = 2; i <= n; ++i)
in >> t[i][0];
t[1][0] = 0;
level[1] = 1;
for (int i = 2; i <= n; ++i)
level[i] = calc_level(i);
for (int i = 1; i <= n; ++i) {
for (int e = 1; e <= LOG; ++e)
t[i][e] = t[t[i][e - 1]][e - 1];
}
for (int i = 1; i <= m; ++i) {
int a, b;
in >> a >> b;
if (level[a] < level[b])
std::swap(a, b);
int level_diff = level[a] - level[b];
a = ancestor(a, level_diff);
// int j = 0;
// while (ancestor(a, j) != ancestor(b, j)) {
// std::cout << "ancestor of a = " << a << " at depth " << j << " is " << ancestor(a, j) << '\n';
// std::cout << "ancestor of b = " << b << " at depth " << j << " is " << ancestor(b, j) << '\n';
// ++j;
// }
int left = 0, right = n, mid, ans = -1;
while (left <= right) {
mid = (left + right) / 2;
if (ancestor(a, mid) == ancestor(b, mid)) {
ans = mid;
right = mid - 1;
}
else
left = mid + 1;
}
assert(ans != -1);
out << ancestor(a, ans) << '\n';
}
return 0;
}