Pagini recente » Cod sursa (job #620963) | Cod sursa (job #994687) | Cod sursa (job #407415) | Rating Haggarth (haggarth) | Cod sursa (job #2150114)
#include <fstream>
#include <map>
#include <vector>
using namespace std;
struct Node
{
int time = 0;
vector<int> sons;
vector<int> ancestors;
};
using Tree = vector<Node>;
void FindAncestors(Tree &t, int node)
{
if (!t[node].ancestors.empty()) {
auto anc = t[node].ancestors[0];
auto ind = 0;
while (ind < (int)t[anc].ancestors.size()) {
auto prev = t[anc].ancestors[ind];
t[node].ancestors.push_back(prev);
anc = prev;
ind += 1;
}
}
for (const auto &son : t[node].sons) {
FindAncestors(t, son);
}
static int time = 0;
t[node].time = ++time;
}
int FindNotGreater(const Tree &t, int a, int b)
{
for (size_t i = 1; i < t[a].ancestors.size(); ++i) {
auto anc = t[a].ancestors[i];
if (t[anc].time > t[b].time) {
return t[a].ancestors[i - 1];
}
}
return t[a].ancestors.back();
}
int FindLca(const Tree &t, int a, int b)
{
if (t[a].time > t[b].time) {
swap(a, b);
}
static map<pair<int, int>, int> memo;
if (memo.count({a, b})) {
return memo[{a, b}];
}
auto init_a = a;
while (a > 0 && t[a].time < t[b].time) {
a = FindNotGreater(t, a, b);
}
return memo[{init_a, b}] = 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) {
int father;
fin >> father;
tree[i].ancestors.push_back(father - 1);
tree[father - 1].sons.push_back(i);
}
FindAncestors(tree, 0);
for (int i = 0; i < queries; ++i) {
int a, b;
fin >> a >> b;
auto lca = FindLca(tree, a - 1, b - 1);
fout << lca + 1 << "\n";
}
return 0;
}