Cod sursa(job #2722269)

Utilizator marius004scarlat marius marius004 Data 12 martie 2021 18:21:17
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.48 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX =  100010;

int n, m, tree[NMAX], euler[2 * NMAX], k, depth[NMAX], level[2 * NMAX], lookup[NMAX], logb2[NMAX], RMQ[20][2 * NMAX];
vector < int > G[NMAX];

void eulerTraversal(int node, int d) {

    euler[++k] = node;
    lookup[node] = k;
    level[k] = d;

    for(auto& it : G[node]) {
        eulerTraversal(it, d + 1);
        euler[++k] = node;
        level[k] = d;
    }
}

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)
        logb2[i] = 1 + logb2[i / 2];

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

    for(int i = 1;i <= logb2[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 dif = logb2[ y - x + 1 ];

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

    return 0;
}