Pagini recente » Cod sursa (job #3210729) | Cod sursa (job #3222467) | Cod sursa (job #3269621) | Cod sursa (job #2908906) | Cod sursa (job #2787800)
#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) {
tree[node].time = euler.size();
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);
}
}
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 = 0; i < (int)euler.size(); i += 1) {
dp[i].push_back(euler[i]);
for (int k = 0; i - (1 << k) >= 0; k += 1) {
if (k >= (int)dp[i - (1 << k)].size()) {
break;
}
auto lnode = dp[i - (1 << k)][k];
auto rnode = dp[i][k];
if (tree[lnode].depth < tree[rnode].depth) {
dp[i].push_back(lnode);
} else {
dp[i].push_back(rnode);
}
}
}
return dp;
}
int Log2(int n) {
static vector<int> memo{0, 0};
while ((int)memo.size() <= n) {
int x = memo.size();
memo.push_back(memo[x / 2] + 1);
}
return memo[n];
}
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 = Log2(r - l + 1);
auto lnode = dp[l + (1 << pow) - 1][pow];
auto rnode = dp[r][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);
}
Log2(nodes);
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;
}