Cod sursa(job #3361944)

Utilizator prodsevenStefan Albu prodseven Data 30 iulie 2026 12:29:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
#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;
}