Cod sursa(job #2643415)

Utilizator pregoliStana Andrei pregoli Data 19 august 2020 19:27:20
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.64 kb
#include "bits/stdc++.h"
#define newline '\n'
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
///***********************
const int NMAX = 1e5 + 3, LMAX = log2(NMAX) + 2;
int n, m, k, log2from[NMAX << 1], fap[NMAX];
pair<int, int> euler[NMAX << 1];
vector<int> arb[NMAX];
int rmq[NMAX << 1][LMAX];//poz de lvl min din intervalu [i,i+2^j-1]

void read() {
    fin >> n >> m;
    for (int i = 2; i <= n; i++) {
        int dad;
        fin >> dad;
        arb[dad].push_back(i);
    }
}

void dfs(int node, int lev) {
    euler[++k] = make_pair(node, lev);
    fap[node] = k;
    for (auto it : arb[node]) {
        dfs(it, lev + 1);
        euler[++k] = make_pair(node, lev);
    }
}

void precompute() {
    for (int i = 2; i <= k; i++)
        log2from[i] = log2from[i >> 1] + 1;
    for (int i = 1; i <= k; i++)
        rmq[i][0] = i;
}

void computeRmq() {
    for (int j = 1; j < LMAX; j++)
        for (int i = 1; i <= k - (1 << j) + 1; i++) {
            int len = (1 << (j - 1));
            rmq[i][j] = rmq[i][j - 1];
            if (euler[rmq[i + len][j - 1]].second < euler[rmq[i][j]].second)
                rmq[i][j] = rmq[i + len][j - 1];
        }
}

int lca(int a, int b) {
    a = fap[a], b = fap[b];
    if (a > b)
        swap(a, b);
    int dif = b - a + 1;
    int p = log2from[dif];
    return euler[min(rmq[a][p], rmq[b - (1 << p) + 1][p])].first;
}

int main() {
    read();
    dfs(1, 0);
    precompute();
    computeRmq();
    while (m--) {
        int a, b;
        fin >> a >> b;
        fout << lca(a, b) << newline;
    }
    fout.close();
    return 0;
}