Pagini recente » Cod sursa (job #1017475) | Cod sursa (job #2547650) | Cod sursa (job #847547) | Cod sursa (job #1428687) | Cod sursa (job #2397896)
#include <cmath>
#include <fstream>
#include <vector>
using namespace std;
struct Node
{
vector<int> sons;
int father = -1;
int ancestor = -1;
int depth = 0;
int bucket;
};
using Tree = vector<Node>;
#include <iostream>
void Dfs(Tree &t, int node, int level, const int kBucketDepth)
{
static auto bucket_id = 0;
auto next_level = level + 1;
if (level >= kBucketDepth) {
next_level = 0;
bucket_id += 1;
t[node].ancestor = t[node].father;
t[node].bucket = (bucket_id += 1);
}
for (const auto &next : t[node].sons) {
t[next].depth = t[node].depth + 1;
t[next].bucket = t[node].bucket;
t[next].ancestor = t[node].ancestor;
t[next].father = node;
Dfs(t, next, next_level, kBucketDepth);
}
}
int SimpleLca(const Tree &t, int a, int b)
{
while (a != b) {
if (t[a].depth >= t[b].depth) {
a = t[a].father;
} else {
b = t[b].father;
}
}
return a;
}
int FindLca(const Tree &t, int a, int b)
{
while (t[a].bucket != t[b].bucket) {
if (t[a].depth >= t[b].depth) {
a = t[a].ancestor;
} else {
b = t[b].ancestor;
}
}
return SimpleLca(t, a, b);
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
int nodes, queries;
fin >> nodes >> queries;
Tree tree(nodes);
for (auto i = 1; i < nodes; i += 1) {
int father;
fin >> father;
tree[father - 1].sons.push_back(i);
}
Dfs(tree, 0, 0, sqrt(nodes));
for (auto i = 0; i < queries; i += 1) {
int a, b;
fin >> a >> b;
auto res = FindLca(tree, a - 1, b - 1);
fout << res + 1 << "\n";
}
return 0;
}