Cod sursa(job #3274355)

Utilizator Radu_BicliBiclineru Radu Radu_Bicli Data 6 februarie 2025 14:51:48
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.4 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");
int n, q, i, rmq[20][200002], x, y;
int tpIn[200002], niv[200002];
vector<int> g[200002];
int lg[200002];

int lung = 0;
static inline void Parc(int nod = 1, int tata = 0, int nivel = 1) {
    tpIn[nod] = ++lung;
    rmq[0][lung] = nod;

    niv[nod] = nivel;

    for(int urm : g[nod]) {
        if(urm != tata) {
            Parc(urm, nod, nivel + 1);
            rmq[0][++lung] = nod;
        }
    }
}

static inline int Min(int a, int b) {
    if(niv[a] < niv[b]) return a;
                        return b;
}

static inline int Query(int st, int dr) {
    if(st > dr) swap(st, dr);
    int k = lg[dr - st];
    return Min(rmq[k][st], rmq[k][dr - (1 << k) + 1]);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    fin >> n >> q;
    for(i = 2; i <= n; i++) {
        int t;
        fin >> t;
        g[t].push_back(i);
    }

    Parc();

    lg[1] = 0;
    for(i = 2; i <= lung; i++) lg[i] = 1 + lg[i >> 1];

    for(int p = 1; p <= lg[lung]; p++) {
        for(i = 1; i <= lung - (1 << p) + 1; i++) {
            rmq[p][i] = Min(rmq[p - 1][i], rmq[p - 1][i + (1 << (p - 1))]);
        }
    }

    while(q--) {
        fin >> x >> y;
        fout << Query(tpIn[x], tpIn[y]) << "\n";
    }

    return 0;
}