Pagini recente » Monitorul de evaluare | Cod sursa (job #3363723) | Cod sursa (job #3361937) | Cod sursa (job #3361952) | Cod sursa (job #3362322)
#include <fstream>
#include <vector>
#include <bitset>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q;
vector<vector<int>> tree;
vector<int> euler, height, first_appearance_idx;
bitset<100005> viz;
const int LOG_N = 20;
vector<int> logs;
vector<vector<int>> sparse_table;
inline int operation(int st_idx_1, int st_idx_2) {
return height[euler[st_idx_1]] <= height[euler[st_idx_2]] ? st_idx_1 : st_idx_2;
}
void precalc_logs() {
logs[1] = 0;
for (int i = 2 ; i < (int)euler.size() ; ++i) {
logs[i] = logs[i / 2] + 1;
}
}
void precalc_sparse_table() {
for (int j = 0 ; j < (int)euler.size() ; ++j) sparse_table[0][j] = j;
for (int i = 1 ; i <= LOG_N ; ++i) {
for (int j = 0 ; j + (1 << i) - 1 < (int)euler.size() ; ++j) {
sparse_table[i][j] = operation(sparse_table[i - 1][j], sparse_table[i - 1][j + (1 << (i - 1))]);
}
}
}
void dfs_euler(int node, int level) {
viz[node] = true;
height[node] = level;
first_appearance_idx[node] = euler.size();
euler.push_back(node);
for (auto nei : tree[node]) {
if (!viz[nei]) {
dfs_euler(nei, level + 1);
euler.push_back(node);
}
}
}
int main() {
cin >> n >> q;
height.resize(n + 2);
first_appearance_idx.resize(n + 2);
tree.resize(n + 2);
for (int son = 1 ; son < n ; ++son) {
int parent; cin >> parent; parent--;
tree[parent].push_back(son);
tree[son].push_back(parent);
}
dfs_euler(0, 0);
sparse_table.resize(LOG_N + 2, vector<int>(euler.size() + 2));
logs.resize(euler.size() + 2);
precalc_logs();
precalc_sparse_table();
for (int i = 1 ; i <= q ; ++i) {
int node1, node2;
cin >> node1 >> node2;
node1--; node2--;
int l = first_appearance_idx[node1], r = first_appearance_idx[node2];
if (l > r) swap(l, r);
int power_length = logs[r - l + 1];
cout << euler[operation(sparse_table[power_length][l], sparse_table[power_length][r - (1 << power_length) + 1])] + 1 << "\n";
}
}