Pagini recente » Cod sursa (job #3357941) | Cod sursa (job #3357972) | Cod sursa (job #3357794) | Cod sursa (job #3357727) | Cod sursa (job #3357725)
#include <iostream>
#include <fstream>
#include <vector>
#include <climits>
#include <algorithm>
std::vector<int> euler;
std::vector<int> depth;
std::vector<int> euler_depth;
std::vector<std::vector<int>> tree;
std::vector<int> first_occurrence;
std::vector<std::vector<int>> st;
std::vector<int> log_table;
void dfs(int node, int d, int &idx) {
depth[node] = d;
first_occurrence[node] = idx;
euler[idx] = node;
euler_depth[idx] = d;
idx++;
for (int child : tree[node]) {
dfs(child, d + 1, idx);
euler[idx] = node;
euler_depth[idx] = d;
idx++;
}
}
void build_sparse_table(int n) {
int k = log_table[n] + 1;
st.assign(k, std::vector<int>(n));
for (int i = 0; i < n; ++i)
st[0][i] = i;
for (int j = 1; j < k; ++j)
for (int i = 0; i + (1 << j) <= n; ++i)
if (euler_depth[st[j-1][i]] < euler_depth[st[j-1][i + (1 << (j-1))]])
st[j][i] = st[j-1][i];
else
st[j][i] = st[j-1][i + (1 << (j-1))];
}
int query_rmq(int l, int r) {
int len = r - l + 1;
int j = log_table[len];
if (euler_depth[st[j][l]] <= euler_depth[st[j][r - (1 << j) + 1]])
return st[j][l];
else
return st[j][r - (1 << j) + 1];
}
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);
first_occurrence.resize(n + 1, -1);
for (int i = 2; i <= n; ++i) {
int parent;
input >> parent;
tree[parent].push_back(i);
}
int euler_size = 2 * n;
euler.resize(euler_size);
euler_depth.resize(euler_size);
int idx = 0;
dfs(1, 0, idx);
int euler_n = idx;
log_table.resize(euler_n + 1);
log_table[1] = 0;
for (int i = 2; i <= euler_n; ++i)
log_table[i] = log_table[i/2] + 1;
build_sparse_table(euler_n);
while (m--) {
int u, v;
input >> u >> v;
int l = first_occurrence[u];
int r = first_occurrence[v];
if (l > r) std::swap(l, r);
int pos = query_rmq(l, r);
output << euler[pos] << '\n';
}
return 0;
}