Cod sursa(job #3178141)

Utilizator juniorOvidiu Rosca junior Data 1 decembrie 2023 09:36:32
Problema Range minimum query Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.37 kb
#include <fstream>

#define NMAX 100001
#define LMAX 17
// 2^17 = 131072

using namespace std;

ifstream fin("rmq.in");
ofstream fout("rmq.out");
int n, i, a[NMAX], m[LMAX][NMAX], s, d, q, lu, lg[NMAX], l;

void dina() {
    int c, l;
    
    for (c = 1; c <= n; c++) // Minimele pentru secventele de lungime 1 = 2^0.
        m[0][c] = a[c];
    for (l = 1; (lu = (1 << l)) <= n; l++)                    // Minimele pentru secvente de lungime 2^l.
        for (c = 1; c + (lu - 1) <= n; c++)                   // Capatul drept sa fie in sir.
            m[l][c] = min(m[l - 1][c], m[l - 1][c + l]); // Comparam minimele din cele 2 jumatati ale intervalului.
}

int main() {
    fin >> n >> q;
    for (i = 1; i <= n; i++)
        fin >> a[i];
    dina();
    lg[1] = 0;
    for (i = 2; i <= n; i++)   // [log2 i]
        lg[i] = lg[i / 2] + 1; // log2 (i / 2) + log2 2 = log2 (i / 2 * 2) = log2 i
    for (i = 1; i <= q; i++) {
        fin >> s >> d;
        lu = d - s + 1;
        l = lg[lu]; // linia din care luam informatiile
        fout << min(m[l][s], m[l][d - (1 << l) + 1]) << '\n';
    }
    return 0;
}

/*
101 110 -> 3   10
101 120 -> 4   20
101 140 -> 5   40

1 5 6 4 3     0
1 5 4 3       1
1 3           2

2^i * 17 - s
s = 1 + 2 + 4 ... = 2^(i-1) - 1

*/

/*

O(log n)
O(n)
O(1)

101    116
   105     120

101        132
*/