Cod sursa(job #2986754)

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

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

const int N = 1e5 + 5;

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

void read(), euler(int, int), buildRMQ();
int query(int, int);

int main()
{
    read(); k = 0;
    euler(1, 0);
    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(){
    f >> n >> m;
    for (int i = 2; i <= n; i++){
        f >> k; fii[k].push_back(i);
    }
}
void euler(int nod, int nivel){
    rmq[0][++k] = nod;
    first[nod] = k;
    h[nod] = nivel;
    for (auto it: fii[nod]){
        euler(it, nivel + 1);
        rmq[0][++k] = nod;
    }
}
void buildRMQ(){
    for (int i = 1, p = 2; p <= k; i++, p *= 2)
        for (int j = 1; j <= k - p; j++)
            rmq[i][j] = (h[rmq[i-1][j]] < h[rmq[i-1][j + p/2]] ? rmq[i-1][j] : rmq[i-1][j + p/2]);
}
int query(int a, int b){
    int l = b - a + 1;
    l = 31 - __builtin_clz(l);
    if (h[rmq[l][a]] > h[rmq[l][b - (1<<l) + 1]])
        return rmq[l][b - (1<<l) + 1];
    return rmq[l][a];
}