Cod sursa(job #2567128)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 3 martie 2020 15:18:38
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <bits/stdc++.h>

#define MAXN    100005
#define LOG2    20

int N, M;
std::vector <int> ADC[MAXN];
inline void addEdge(int u, int v) {
    ADC[u].push_back(v);
    ADC[v].push_back(u);
}

int depth[MAXN], first[MAXN];
int RMQ[LOG2][2*MAXN], logtable[2*MAXN];
std::vector <int> euler;
void DFS(int vertex = 1, int parent = 0) {
    first[vertex] = euler.size();
    depth[vertex] = depth[parent]+1;
    euler.push_back(vertex);
    for (auto &it:ADC[vertex]) {
        if (it == parent) continue;
        DFS(it, vertex);
        euler.push_back(vertex);
    }
}
void computeRMQ() {
    for (int i=2; i<2*MAXN; ++i)
        logtable[i] = logtable[i/2] + 1;
    for (int i=0; i<euler.size(); ++i)
        RMQ[0][i] = euler[i];
    for (int i=1; i<LOG2; ++i)
        for (int j=1, k=(1<<i); k<euler.size(); ++j, ++k)
            RMQ[i][j] = (depth[RMQ[i-1][j]] < depth[RMQ[i-1][j + (1<<(i-1))]] ? RMQ[i-1][j] : RMQ[i-1][j + (1<<(i-1))]);
}
int LCA(int u, int v) {
    if (u == v) return u;
    int x = first[u];
    int y = first[v];
    if (x > y) std::swap(x, y);
    int len = logtable[y-x+1];
    int c1 = RMQ[len][x];
    int c2 = RMQ[len][y-(1<<len)+1];
    if (depth[c1] < depth[c2]) return c1;
    return c2;
}

#define FILENAME    std::string("lca")
std::ifstream input (FILENAME+".in");
std::ofstream output(FILENAME+".out");

int32_t main()
{
    input >> N >> M;
    for (int i=1, u; i<N; ++i)
        input >> u, addEdge(u, i+1);
    DFS();
    computeRMQ();
    for (int i=1, x, y; i<=M; ++i)
        input >> x >> y, output << LCA(x, y) << '\n';

    return 0;
}