Cod sursa(job #2720481)

Utilizator marius004scarlat marius marius004 Data 10 martie 2021 21:29:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.64 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 100001;
const int LOG = 20;

int n, m, euler[2 * NMAX], level[2 * NMAX], k, logarithm[2 * NMAX], RMQ[LOG][2 * NMAX], lookup[NMAX];
vector < int > G[NMAX];

void eulerTraversal(int node, int l) {
    euler[++k] = node;
    level[k] = l;
    lookup[node] = k; /// pe ce pozitie se afla node in parcurgerea euler

    for(auto& it : G[node]) {
        eulerTraversal(it, l + 1);
        euler[++k] = node;
        level[k]   = l; /////// BE CAREFUL HERE.
    }
}

int main() {

    f >> n >> m;

    for (int i = 2; i <= n; ++i) {
        int x;
        f >> x;
        G[x].push_back(i);
    }

    eulerTraversal(1, 1);

    for (int i = 2; i <= k; ++i)
        logarithm[i] = 1 + logarithm[i / 2];

    /// fac RMQ
    for (int i = 1; i <= k; ++i)
        RMQ[0][i] = i;

    for (int i = 1; i <= logarithm[k] + 1; ++i){
        for (int j = 1; j <= k; ++j) {

            RMQ[i][j] = RMQ[i - 1][j];

            if(j + (1 << (i - 1)) <= k &&
                level[ RMQ[i - 1][j] ] > level[ RMQ[i - 1][j + (1 << (i - 1) ) ] ]) {
                RMQ[i][j] = RMQ[i - 1][j + (1 << (i - 1))];
            }
        }
    }

    for(;m--;) {

        int x, y;
        f >> x >> y;

        x = lookup[x];
        y = lookup[y];

        if(x > y)
            swap(x, y);

        int logg = logarithm[y - x + 1];

        if(level[ RMQ[logg][x] ] < level[ RMQ[logg][ y - (1 << logg) + 1 ] ])
            g << euler[ RMQ[logg][x] ] << '\n';
        else
            g << euler[ RMQ[logg][ y - (1 << logg) + 1 ] ] << '\n';
    }

    return 0;
}