Pagini recente » Cod sursa (job #2826435) | Cod sursa (job #2843980) | Cod sursa (job #2830354) | Cod sursa (job #3226664) | Cod sursa (job #2037996)
#include <cmath>
#include <fstream>
#include <utility>
#include <vector>
std::ifstream r("lca.in");
std::ofstream w("lca.out");
class RMQ {
public:
RMQ(const std::vector<int>& levels) : levels_(levels) {}
void build() {
size_t size = levels_.size();
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];
}
}
private:
const std::vector<int>& levels_;
std::vector<std::vector<int>> matrix_;
};
class LCA {
public:
LCA(int n)
: length(0),
euler(2 * n - 1),
levels(2 * n - 1),
index(n + 1),
rmq(levels) {}
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();
}
int query(int a, int b) {
return euler[rmq.query(index[a], index[b])];
}
private:
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 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;
}