Cod sursa(job #3201364)

Utilizator AndyGooShooterDurlea Andrei AndyGooShooter Data 7 februarie 2024 19:16:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
// https://www.infoarena.ro/problema/lca

#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
using namespace std;

string __fname = "lca"; ifstream in (__fname + ".in"); ofstream out (__fname + ".out"); 
#define cin in 
#define cout out

int n, m;
vector<vector<int>> sparseTable;
vector<vector<int>> adjacencyList;
vector<int> level;

void buildSparseTable(){
    for(int k = 1; k <= 20; k ++){
        for(int i = 1; i <= n; i ++)
            sparseTable[i][k] = sparseTable[sparseTable[i][k - 1]][k - 1];
    }
}

void DFS(int source, int parent){
    for(int i : adjacencyList[source]){
        if(i == parent) continue;

        level[i] = level[source] + 1;
        DFS(i, source);
    }
}

int LCA(int a, int b){
    if(level[a] > level[b])
        swap(a, b);

    // b is always bigger than a

    int k = level[b] - level[a];
    // getting a on the same level as b
    for(int i = 20; i >= 0; i --){
        if(k >= (1 << i)){ // k includes bit i
            b = sparseTable[b][i];
            k -= (1 << i);
        }
    }

    if(a == b) return a; // b was an ancestor of a or viceversa

    // binary search
    for(int i = 20; i >= 0; i --){
        if(sparseTable[a][i] == sparseTable[b][i]) continue;

        a = sparseTable[a][i];
        b = sparseTable[b][i];
    }

    return sparseTable[a][0];

}

int main(){

    cin >> n;
    cin >> m;
    sparseTable.resize(n + 1, vector<int>(21));
    adjacencyList.resize(n + 1);
    level.resize(n + 1, 0);

    for(int i = 2; i <= n; i ++){
        // build sparse seeds
        cin >> sparseTable[i][0];

        // build level list
        adjacencyList[sparseTable[i][0]].push_back(i);
    }
    DFS(1, 0);
    buildSparseTable();

    for(int i = 1; i <= m; i ++){
        int a, b;
        cin >> a >> b;

        cout << LCA(a, b) << '\n';
    }

    return 0;
}