Cod sursa(job #3030792)

Utilizator maiaauUngureanu Maia maiaau Data 17 martie 2023 21:21:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.25 kb
#include <bits/stdc++.h>
using namespace std;

#define pb push_back

ifstream f("lca.in");
ofstream g("lca.out");

const int N = 1e5 + 5;

int n, m, x, y, k, first[N], niv[N], rmq[18][2 * N];
vector<int> fii[N];

void read(), dfs(int, int), buildRmq();
int query(int, int);

int main()
{
    read();
    dfs(1, 1);
    buildRmq();
    for (; m; m--){
        f >> x >> y;
        x = first[x]; y = first[y];
        if (x > y) swap(x, y);
        g << query(x, y) << '\n';
    }

    return 0;
}

void read(){
    int tata;
    f >> n >> m;
    for (int i = 2; i <= n; i++){
        f >> tata;
        fii[tata].pb(i);
    }
}
void dfs(int nod, int h){
    rmq[0][++k] = nod; niv[nod] = h;
    if(!first[nod]) first[nod] = k;
    for (auto it: fii[nod]){
        dfs(it, h + 1);
        rmq[0][++k] = nod;
    }
}
void buildRmq(){
    for (int i = 1, p = 1; 2 * p <= k; i++, p *= 2)
        for (int j = 1; j + p <= k; j++)
            rmq[i][j] = (niv[rmq[i - 1][j]] < niv[rmq[i - 1][j + p]] ? rmq[i - 1][j] : rmq[i - 1][j + p]);
}
int query(int l, int r){
    int pw = r - l + 1;
    pw = 31 - __builtin_clz(pw);
    int a = rmq[pw][l], b = rmq[pw][r - (1<<pw) + 1];
    if (niv[a] > niv[b]) return b;
    return a;
}