Cod sursa(job #3334306)

Utilizator NeamtuMateiNeamtu Matei-Constantin NeamtuMatei Data 17 ianuarie 2026 10:24:52
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.85 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

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

const int MAXN = 1e5;
const int LOGN = 17;

struct remeq {
    int val;
    int nod;
};

int _n, n, m, tata, a, b;
remeq rmq[3*MAXN+1][LOGN+5];
int lg2[3*MAXN+1];

vector<int> graf[MAXN+1];
vector<int> euler, nivele;
vector<int> aparitii(MAXN+1, -1);

void dfs_euler(int nod, int nivel) {
    euler.push_back(nod);
    nivele.push_back(nivel);

    if (aparitii[nod] == -1)
        aparitii[nod] = euler.size() - 1;

    for (auto e: graf[nod]) {
        dfs_euler(e, nivel + 1);

        euler.push_back(nod);
        nivele.push_back(nivel);
    }
}

int main() {
    in >> _n >> m;
    for (int i = 2; i <= _n; i++) {
        in >> tata;
        graf[tata].push_back(i);
    }

    dfs_euler(1, 0);
    n = euler.size();

    // init the rmq
    for (int i = 1; i <= n; i++)
        rmq[0][i] = { nivele[i-1], euler[i-1] };

    // build log2 vector
    lg2[0] = lg2[1] = 0;
    for (int i = 2; i <= n; i++)
        lg2[i] = lg2[i / 2] + 1;

    // build the rmq
    for (int i = 1; i <= lg2[n]; i++) {
        for (int j = 1; j <= n - (1 << i) + 1; j++)
            if (rmq[i-1][j].val < rmq[i-1][j + (1 << (i - 1))].val)
                rmq[i][j] = rmq[i-1][j];
            else
                rmq[i][j] = rmq[i-1][j + (1 << (i - 1))];
    }

    for (int q = 1; q <= m; q++) {
        int _a, _b;
        in >> _a >> _b;

        a = aparitii[min(_a, _b)] + 1, b = aparitii[max(_a, _b)] + 1;

        int nk = lg2[b - a];

        remeq st = rmq[nk][a];
        remeq dr = rmq[nk][b - (1 << nk) + 1];

        if (st.val < dr.val)
            out << st.nod << '\n';
        else
            out << dr.nod << '\n';
    }

    return 0;
}