Pagini recente » Cod sursa (job #1968071) | Cod sursa (job #2938170) | Cod sursa (job #2049549) | Cod sursa (job #85526) | Cod sursa (job #2037993)
#include <cmath>
#include <fstream>
#include <utility>
#include <vector>
std::ifstream r("lca.in");
std::ofstream w("lca.out");
struct RMQ {
RMQ(const std::vector<int>& levels) : levels_(levels) {}
void build() {
w.flush();
size_t size = levels_.size();
w.flush();
matrix_.resize(size);
size_t pos = 0;
for (size_t i = 0; i < size; i++) {
matrix_[i].resize(1 + (int) (std::log(size) / std::log(2)));
matrix_[i][0] = i;
}
for (size_t d = 1; d < matrix_.front().size(); d++) {
for (size_t i = 0; i < size; i++) {
matrix_[i][d] = matrix_[i][d - 1];
pos = i + (1 << (d - 1));
if (pos < size) {
if (levels_[matrix_[i][d]] > levels_[matrix_[pos][d - 1]]) {
matrix_[i][d] = matrix_[pos][d - 1];
}
}
}
}
}
int query(int a, int b) {
if (a > b) {
std::swap(a, b);
}
int d = (int) (std::log(b - a + 1) / std::log(2));
int pos = b - (1 << d) + 1;
if (levels_[matrix_[a][d]] < levels_[matrix_[pos][d]]) {
return matrix_[a][d];
} else {
return matrix_[pos][d];
}
}
const std::vector<int>& levels_;
std::vector<std::vector<int>> matrix_;
};
struct LCA {
LCA(int n) : length(0), rmq(levels) {
euler.resize(2 * n - 1);
levels.resize(2 * n - 1);
index.resize(n + 1);
}
void read() {
std::vector<std::vector<int>> children;
children.resize(index.size());
int parent;
for (size_t i = 2; i < index.size(); i++) {
r >> parent;
children[parent].emplace_back(i);
}
eulerTraverse(1, 0, children);
rmq.build();
}
void eulerTraverse(
int idx, int lvl, const std::vector<std::vector<int>>& children) {
for (const auto& child : children[idx]) {
save(idx, lvl);
eulerTraverse(child, lvl + 1, children);
}
save(idx, lvl);
}
void save(int idx, int lvl) {
index[idx] = length;
euler[length] = idx;
levels[length] = lvl;
length++;
}
int query(int a, int b) {
return euler[rmq.query(index[a], index[b])];
}
int length;
std::vector<int> euler;
std::vector<int> levels;
std::vector<int> index;
RMQ rmq;
};
int main() {
int n, tests, a, b;
r >> n >> tests;
LCA tree(n);
tree.read();
while (tests--) {
r >> a >> b;
w << tree.query(a, b) << "\n";
}
return 0;
}