Cod sursa(job #3313591)

Utilizator Victor321321Victor Casandra Victor321321 Data 5 octombrie 2025 13:27:39
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 100005;
const int LMAX = 2 * NMAX;

int n, m;
vector<int> G[NMAX];
int viz[NMAX];
int euler[LMAX];
int euler_nivel[LMAX];
int first[NMAX];
int cnt = 0;
int lg2_[LMAX];
int rmq[20][LMAX];

void dfs(int x, int nv) {
    viz[x] = 1;
    euler[++cnt] = x;
    euler_nivel[cnt] = nv;
    first[x] = cnt;
    for (auto vecin : G[x]) {
        dfs(vecin, nv + 1);
        euler[++cnt] = x;
        euler_nivel[cnt] = nv;
    }
}
void build_rmq() {
    for (int i = 2; i <= cnt; i++) lg2_[i] = lg2_[i / 2] + 1;
    for (int i = 1; i <= cnt; i++) rmq[0][i] = i;

    for (int k = 1; (1 << k) <= cnt; k++) {
        for (int i = 1; i + (1 << k) - 1 <= cnt; i++) {
            int a = rmq[k - 1][i];
            int b = rmq[k - 1][i + (1 << (k - 1))];
            rmq[k][i] = (euler_nivel[a] < euler_nivel[b] ? a : b);
        }
    }
}

int rmq_euler_nivel(int l, int r) {
    if (l > r) swap(l, r);
    int k = lg2_[r - l + 1];
    int a = rmq[k][l];
    int b = rmq[k][r - (1 << k) + 1];
    return (euler_nivel[a] < euler_nivel[b] ? a : b);
}

int LCA(int x, int y) {
    int indice = rmq_euler_nivel(first[x], first[y]);
    return euler[indice];
}

int main() {

    fin >> n >> m;
    for (int i = 2; i <= n; i++) {
        int p;
        fin >> p;
        G[p].push_back(i);
    }
    dfs(1, 0);
    build_rmq();
    while (m--) {
        int u, v;
        cin >> u >> v;
        cout << LCA(u, v) << "\n";
    }
    return 0;
}