Cod sursa(job #2553083)

Utilizator KPP17Popescu Paul KPP17 Data 21 februarie 2020 16:37:09
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
using namespace std;


#define fisier "rmq"

#ifdef fisier
    #include <fstream>
    ifstream in(fisier ".in");
    ofstream out(fisier ".out");
#else
    #include <iostream>
    #define in cin
    #define out cout
#endif



const int
MAX_N = 100000,
LOG2_MAX_N = 17;

int n, m, d[LOG2_MAX_N][MAX_N], doi_la[32];

int log2(int x) {
    int i = 0, j = 31, mij;
    while (i <= j) {
        mij = (i + j) / 2;
        if (doi_la[mij] <= x) {
            i = mij + 1;
        } else {
            j = mij - 1;
        }
    }
    if (j == -1) {
        return 0;

    }

    return j;

}



void constr_puteri_doi() {

    *doi_la = 1;

    for (int i = 1; i < 31; i++) {

        doi_la[i] = doi_la[i - 1] << 1;

    }

}



void constr_d() {

    in >> n >> m;

    for (int i = 0; i < n; i++) {

        in >> (*d)[i];

    }



    int log2_n = log2(n);

    for (int exp = 1; exp <= log2_n; exp++) {

        int
        prev_lun = doi_la[exp - 1],
        start_cap = n - prev_lun;

        for (int start = 0; start < n; start++) {

            d[exp][start] = d[exp - 1][start];

            if (start < start_cap) {

                d[exp][start] = min(d[exp][start], d[exp - 1][start + prev_lun]);

            }

        }

    }

}



int main() {

    constr_puteri_doi();
    constr_d();

    int x, y, log2_lun, L[MAX_N + 1];

    L[1] = 0;
    for (int i=2;i<=n;i++)
        L[i] = 1+L[i/2];


///    1 2 3 4 5 6 7 8 9 10 11 12
///    0 1 1 2 2 2 2 3 3  3  3  3

    while (m--) {

        in >> x >> y;
        x--; y--;

///        log2_lun = log2(y - x);
        log2_lun = L[y - x];

        out << min(d[log2_lun][x], d[log2_lun][y - (1<<log2_lun)+1]) << '\n';

    }

}

/// chiar nu ma asteptam sa mearga codul la prima incercare
// edit: nu merge defapt
// edit: acum cred ca merge
// edit: chiar nu merge














//