Pagini recente » Cod sursa (job #1919111) | Cod sursa (job #1297823) | Cod sursa (job #255620) | Cod sursa (job #897383) | Cod sursa (job #2990557)
#include <iostream>
#include <fstream>
#include <vector>
std::vector<int> euler(1, 0);
std::vector<int> depth;
std::vector<int> euler_depth(1, 0);
std::vector<std::vector<int>> tree;
std::vector<int> pos;
std::vector<int> rmq;
void dfs(int start) {
for (const auto &x: tree[start]) {
euler.push_back(start);
depth[x] = depth[start] + 1;
euler_depth.push_back(depth[start]);
dfs(x);
}
euler.push_back(start);
euler_depth.push_back(depth[start]);
}
int main() {
std::ifstream input("lca.in");
std::ofstream output("lca.out");
int n, m;
input >> n >> m;
tree.resize(n + 1);
depth.resize(n + 1, 0);
pos.resize(n + 1, INT32_MAX);
for (int i = 2; i <= n; ++i) {
int x;
input >> x;
tree[x].push_back(i);
}
dfs(1);
size_t s = euler.size();
for (size_t i = 0; i < s; ++i) {
pos[euler[i]] = std::min<int>(pos[euler[i]], i);
}
int root = 1;
while (root * root <= s) root++;
root--;
int k = 0;
while (k * root + 1 <= s) {
int min = INT32_MAX;
int min_pos = 0;
for (int i = k * root + 1; i <= std::min<int>((k + 1) * root, s - 1); ++i) {
if (euler_depth[i] < min) {
min = euler_depth[i];
min_pos = i;
}
}
rmq.push_back(min_pos);
k++;
}
while (m--) {
int p, q;
input >> p >> q;
int left = std::min(pos[p], pos[q]);
int right = std::max(pos[p], pos[q]);
int min = INT32_MAX;
int min_pos = 0;
for (int i = (left - 1) / root + 1; i < (right - 1) / root; ++i) {
if (euler_depth[rmq[i]] < min) {
min = euler_depth[rmq[i]];
min_pos = rmq[i];
}
}
for (int i = std::max((right - 1) / root * root, left); i <= right; ++i) {
if (euler_depth[i] < min) {
min = euler_depth[i];
min_pos = i;
}
}
for (int i = left; i < std::min(((left - 1) / root + 1) * root + 1, right + 1); ++i) {
if (euler_depth[i] < min) {
min = euler_depth[i];
min_pos = i;
}
}
output << euler[min_pos] << '\n';
}
return 0;
}