Pagini recente » Cod sursa (job #1522836) | Cod sursa (job #2275787) | Cod sursa (job #2226826) | Cod sursa (job #2274517) | Cod sursa (job #2262004)
#include <fstream>
#include <vector>
using namespace std;
struct Node
{
int time = 0;
vector<int> ancestors;
vector<int> sons;
};
using Tree = vector<Node>;
void FindAncestors(Tree &t, int node)
{
auto anc = t[node].ancestors[0];
auto order = 0;
while (order < (int)t[anc].ancestors.size()) {
auto other_anc = t[anc].ancestors[order];
t[node].ancestors.push_back(other_anc);
anc = other_anc;
order += 1;
}
}
void Dfs(Tree &t, int node)
{
if (!t[node].ancestors.empty()) {
FindAncestors(t, node);
}
for (const auto &son : t[node].sons) {
Dfs(t, son);
}
static auto time = 0;
t[node].time = (time += 1);
}
int GetNearAncestor(const Tree &t, int node, int max_time)
{
auto index = 0;
auto power = (1 << 17);
while (power > 0) {
auto next_index = index + power;
power >>= 1;
if (next_index < (int)t[node].ancestors.size()) {
auto anc = t[node].ancestors[next_index];
if (t[anc].time <= max_time) {
index = next_index;
}
}
}
return t[node].ancestors[index];
}
int GetLca(const Tree &t, int a, int b)
{
if (t[a].time > t[b].time) {
swap(a, b);
}
while (t[a].time < t[b].time) {
a = GetNearAncestor(t, a, t[b].time);
}
return a;
}
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 father;
fin >> father;
tree[father - 1].sons.push_back(i);
tree[i].ancestors.push_back(father - 1);
}
Dfs(tree, 0);
for (auto i = 0; i < queries; i += 1) {
int a, b;
fin >> a >> b;
auto lca = GetLca(tree, a - 1, b - 1);
fout << lca + 1 << "\n";
}
return 0;
}