Cod sursa(job #3142740)

Utilizator Mihai_OctMihai Octavian Mihai_Oct Data 24 iulie 2023 09:53:53
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.34 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");
int e[100002], l[100002];
int n, q, i, x, y, k;
int pr[100002], lg[100002];
int rmq[20][100002];
vector<int> t[100002];

static inline void parc(int x, int p) {
    e[++k] = x;
    l[k] = p;
    pr[x] = k;

    for(auto it : t[x]) {
        parc(it, p + 1);
        e[++k] = x;
        l[k] = p;
    }
}

static inline void Rmq() {
    for(int i = 2; i <= k; i++) lg[i] = lg[(i >> 1)] + 1;
    for(int i = 1; i <= k; i++) rmq[0][i] = i;
    for(int i = 1; (1 << i) < k; i++) {
        for(int j = 1; j <= k - (1 << i); j++) {
            int q = (1 << (i - 1));

            rmq[i][j] = rmq[i - 1][j];
            if(l[rmq[i - 1][j + q]] < l[rmq[i][j]]) rmq[i][j] = rmq[i - 1][j + q];
        }
    }
}

static inline int lca(int x, int y) {
    int a = pr[x];
    int b = pr[y];
    if(a > b) swap(a, b);
    int df = b - a;
    int ldf = lg[df];
    int r = rmq[ldf][a];
    df -= (1 << ldf);
    if(l[r] > l[rmq[ldf][a + df]]) r = rmq[ldf][a + df];
    return e[r];
}

int main() {
    fin >> n >> q;
    for(i = 2; i <= n; i++) {
        fin >> x;
        t[x].push_back(i);
    }
    parc(1, 0);
    Rmq();
    while(q--) {
        fin >> x >> y;
        fout << lca(x, y) << "\n";
    }

    return 0;
}