Pagini recente » Cod sursa (job #3360332) | Cod sursa (job #3361322) | Cod sursa (job #3360333) | Cod sursa (job #3361489) | Cod sursa (job #3361944)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q;
struct Node {
int depth;
int idx;
Node *parent;
Node *jump;
};
vector<Node*> all_nodes;
void make_leaf(Node *parent, int idx) {
Node *leaf = new Node();
all_nodes.push_back(leaf);
leaf->depth = parent->depth + 1;
leaf->idx = idx;
leaf->parent = parent;
Node *jump = parent->jump;
if (parent->depth - jump->depth == jump->depth - jump->jump->depth) {
leaf->jump = jump->jump;
} else {
leaf->jump = parent;
}
}
void make_root() {
Node *root = new Node();
all_nodes.push_back(root);
root->depth = 0;
root->idx = 0;
root->parent = nullptr;
root->jump = root;
}
void exit() {
for (auto pointer : all_nodes) delete pointer;
all_nodes.clear();
}
Node* find_anc(Node *node, int depth) {
if (depth < 0) return all_nodes[0];
while (node->depth > depth) {
if (node->jump->depth < depth) {
node = node->parent;
} else {
node = node->jump;
}
}
return node;
}
int main() {
cin >> n >> q;
make_root();
for (int node_idx = 1 ; node_idx < n ; ++node_idx) {
int parent; cin >> parent;
make_leaf(all_nodes[parent - 1], node_idx);
}
for (int i = 1 ; i <= q ; ++i) {
int n1, n2;
cin >> n1 >> n2;
n1--; n2--;
Node *node1 = all_nodes[n1], *node2 = all_nodes[n2];
if (node1->depth > node2->depth) swap(node1, node2);
// we will bring node2 to the depth of node1
node2 = find_anc(node2, node1->depth);
// if true, then node1 was lca and they now coincide
if (node1 == node2) {
cout << node1->idx + 1 << "\n";
continue;
}
// binary lift at the same time until the nodes coincide
while (node1 != node2) {
if (node1->jump != node2->jump) {
node1 = node1->jump;
node2 = node2->jump;
} else {
node1 = node1->parent;
node2 = node2->parent;
}
}
cout << node1->idx + 1 << "\n";
}
exit();
return 0;
}