Cod sursa(job #3357725)

Utilizator TestLicenta123Test Test TestLicenta123 Data 13 iunie 2026 13:14:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.15 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <climits>
#include <algorithm>

std::vector<int> euler;
std::vector<int> depth;
std::vector<int> euler_depth;
std::vector<std::vector<int>> tree;
std::vector<int> first_occurrence;
std::vector<std::vector<int>> st;
std::vector<int> log_table;

void dfs(int node, int d, int &idx) {
    depth[node] = d;
    first_occurrence[node] = idx;
    euler[idx] = node;
    euler_depth[idx] = d;
    idx++;

    for (int child : tree[node]) {
        dfs(child, d + 1, idx);
        euler[idx] = node;
        euler_depth[idx] = d;
        idx++;
    }
}

void build_sparse_table(int n) {
    int k = log_table[n] + 1;
    st.assign(k, std::vector<int>(n));

    for (int i = 0; i < n; ++i)
        st[0][i] = i;

    for (int j = 1; j < k; ++j)
        for (int i = 0; i + (1 << j) <= n; ++i)
            if (euler_depth[st[j-1][i]] < euler_depth[st[j-1][i + (1 << (j-1))]])
                st[j][i] = st[j-1][i];
            else
                st[j][i] = st[j-1][i + (1 << (j-1))];
}

int query_rmq(int l, int r) {
    int len = r - l + 1;
    int j = log_table[len];
    if (euler_depth[st[j][l]] <= euler_depth[st[j][r - (1 << j) + 1]])
        return st[j][l];
    else
        return st[j][r - (1 << j) + 1];
}

int main() {
    std::ifstream input("lca.in");
    std::ofstream output("lca.out");

    int n, m;
    input >> n >> m;

    tree.resize(n + 1);
    depth.resize(n + 1);
    first_occurrence.resize(n + 1, -1);

    for (int i = 2; i <= n; ++i) {
        int parent;
        input >> parent;
        tree[parent].push_back(i);
    }

    int euler_size = 2 * n;
    euler.resize(euler_size);
    euler_depth.resize(euler_size);
    int idx = 0;
    dfs(1, 0, idx);

    int euler_n = idx;

    log_table.resize(euler_n + 1);
    log_table[1] = 0;
    for (int i = 2; i <= euler_n; ++i)
        log_table[i] = log_table[i/2] + 1;

    build_sparse_table(euler_n);

    while (m--) {
        int u, v;
        input >> u >> v;
        int l = first_occurrence[u];
        int r = first_occurrence[v];
        if (l > r) std::swap(l, r);
        int pos = query_rmq(l, r);
        output << euler[pos] << '\n';
    }

    return 0;
}