Pagini recente » Cod sursa (job #870080) | Cod sursa (job #2253949) | Cod sursa (job #2144504) | Cod sursa (job #2489347) | Cod sursa (job #2787790)
#include <fstream>
#include <vector>
using namespace std;
struct Node {
vector<int> edges;
int depth = 0;
int time = 0;
};
using Tree = vector<Node>;
void Euler(Tree& tree, int node, vector<int>& euler) {
euler.push_back(node);
for (const auto& next : tree[node].edges) {
tree[next].depth = tree[node].depth + 1;
Euler(tree, next, euler);
euler.push_back(node);
}
tree[node].time = euler.size();
euler.push_back(node);
}
vector<vector<int>> Precalc(Tree& tree) {
vector<int> euler;
tree[0].depth = 0;
Euler(tree, 0, euler);
vector<vector<int>> dp(euler.size());
for (int i = euler.size() - 1; i >= 0; i -= 1) {
int right = i + 1;
dp[i].push_back(euler[i]);
for (int k = 0; right < (int)dp.size() && k < (int)dp[right].size(); k += 1) {
auto lnode = dp[i][k];
auto rnode = dp[right][k];
if (tree[lnode].depth < tree[rnode].depth) {
dp[i].push_back(lnode);
} else {
dp[i].push_back(rnode);
}
right = i + (1 << (k + 1));
}
}
return dp;
}
int Lca(const Tree& tree, const vector<vector<int>>& dp, int a, int b) {
auto l = min(tree[a].time, tree[b].time);
auto r = max(tree[a].time, tree[b].time);
int pow = 0;
while ((1 << (pow + 1)) <= (r - l + 1)) {
pow += 1;
}
if ((1 << pow) == (r - l + 1)) {
return dp[l][pow];
}
auto lnode = dp[l][pow];
auto rnode = dp[r - (1 << pow) + 1][pow];
return tree[lnode].depth < tree[rnode].depth ? lnode : rnode;
}
int main() {
ifstream fin("lca.in");
ofstream fout("lca.out");
int nodes, queries;
fin >> nodes >> queries;
Tree tree(nodes);
for (int i = 1; i < nodes; i += 1) {
int parent;
fin >> parent;
tree[parent - 1].edges.push_back(i);
}
auto dp = Precalc(tree);
for (int i = 0; i < queries; i += 1) {
int a, b;
fin >> a >> b;
fout << Lca(tree, dp, a - 1, b - 1) + 1 << "\n";
}
return 0;
}