Cod sursa(job #2984938)

Utilizator rastervcrastervc rastervc Data 25 februarie 2023 11:35:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.68 kb
#include <fstream>
#include <vector>
#include <iostream>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

constexpr int LIM = 100005;
constexpr int LG = 25;

int N, M, node, cnt, first[LIM], lg2[2 * LIM];
pair<int, int> RMQ[LG][2 * LIM];
vector<int> G[LIM];

static void dfs(int node, int level) {
    RMQ[0][++cnt] = { node, level };
    first[node] = cnt;
    for (const int adj : G[node]) {
        dfs(adj, level + 1);
        RMQ[0][++cnt] = { node, level };
    }
}

static inline void prepare_LCA() {
    dfs(1, 1);

    for (int i = 1; i < LG; ++i)
        for (int j = 1; j <= cnt; ++j) {
            RMQ[i][j] = RMQ[i - 1][j];
            if (j + (1 << (i - 1)) <= cnt) {
                if (RMQ[i][j].second > RMQ[i - 1][j + (1 << (i - 1))].second)
                    RMQ[i][j] = RMQ[i - 1][j + (1 << (i - 1))];
            }
        }

    lg2[1] = 0;
    for (int i = 2; i <= cnt; ++i)
        lg2[i] = lg2[i / 2] + 1;
}

static inline int LCA(int node1, int node2) {
    int l = first[node1], r = first[node2];
    if (l > r) swap(l, r);

    const int len = r - l + 1;
    int lg_len = lg2[len];
    pair<int, int> RMQ1 = RMQ[lg_len][l];
    pair<int, int> RMQ2 = RMQ[lg_len][r - (1 << lg_len) + 1];

    if (RMQ1.second < RMQ2.second) 
        return RMQ1.first;
    return RMQ2.first;
}

int main() {
    fin >> N >> M;
    for (int i = 2; i <= N; ++i) {
        fin >> node;
        G[node].push_back(i);
    }

    prepare_LCA();

    int node1, node2;
    for (; M; --M) {
        fin >> node1 >> node2;
        fout << LCA(node1, node2) << '\n';
    }

    fin.close();
    fout.close();
    return 0;
}