Pagini recente » Cod sursa (job #1359612) | Cod sursa (job #2858078) | Cod sursa (job #3178327) | Cod sursa (job #2737196) | Cod sursa (job #2730919)
#include <iostream>
#include <fstream>
#include <vector>
const int LOG = 16;
const int NMAX = 1e5;
int euler_len = 0;
int rmq[1 + 2 * NMAX][1 + LOG];
std::vector<int> graph[1 + NMAX];
int level[1 + NMAX];
int first_ap[1 + NMAX];
int last_p2[1 + NMAX];
void euler_repr(int node, int depth) {
rmq[++euler_len][0] = node;
level[node] = depth;
first_ap[node] = euler_len;
for (int next: graph[node]) {
euler_repr(next, depth + 1);
rmq[++euler_len][0] = node;
level[node] = depth;
}
}
inline void build_rmq() {
for (int depth = 1; depth <= LOG; ++depth) {
for (int i = 1; i <= euler_len - (1 << depth) + 1; ++i) {
int min_left = rmq[i][depth - 1];
int min_right = rmq[i + (1 << (depth - 1))][depth - 1];
if (level[min_left] < level[min_right])
rmq[i][depth] = min_left;
else
rmq[i][depth] = min_right;
}
}
}
int main() {
std::ifstream in("lca.in");
std::ofstream out("lca.out");
int exp = 1;
for (int i = 1; i <= NMAX; ++i) {
if ((1 << (exp + 1)) <= i)
++exp;
last_p2[i] = exp;
}
int n, m;
in >> n >> m;
for (int i = 2; i <= n; ++i) {
int t;
in >> t;
graph[t].push_back(i);
}
euler_repr(1, 1);
build_rmq();
// for (int i = 1; i <= euler_len; ++i)
// std::cout << rmq[i][0] << ' ';
// std::cout << '\n';
//
// for (int i = 1; i <= euler_len; ++i) {
// std::cout << rmq[i][0] << ": ";
// for (int j = 0; j <= LOG; ++j)
// std::cout << rmq[i][j] << ' ';
// std::cout << '\n';
// }
for (int i = 1; i <= m; ++i) {
int a, b;
in >> a >> b;
a = first_ap[a];
b = first_ap[b];
if (a > b)
std::swap(a, b);
int len = last_p2[b - a];
int min_left = rmq[a][len];
int min_right = rmq[b - (1 << len)][len];
if (level[min_left] < level[min_right])
out << min_left << '\n';
else
out << min_right << '\n';
}
return 0;
}