Cod sursa(job #2622209)

Utilizator lauratenderLaura Tender lauratender Data 31 mai 2020 17:57:03
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.4 kb
#include <fstream>

std::ifstream in ("rmq.in");
std::ofstream out ("rmq.out");

const int MAXN = 100000;
const int LOGN = 18;

int minim(int a, int b){
    return (a < b) ? a : b;
}

int v[MAXN + 1][LOGN], lg[MAXN + 1]; //v[i][j] este minimul de la i la i + 2^j, iar lg[i] = int(log2 i)

int main()
{
    int N, M, pow = 1, st, dr, pas;
    in >> N >> M;

    for(int i = 2; i <= N; ++i) // intrucat avem nevoie de logaritmul dintre 2 pozitii este suficient sa calculam pentru (1, N)
        lg [i] = lg [i/2] + 1;

    for(int i = 0; i < N; ++i) // citesc numerele si le introduc in structura in in care calculez rmq
        in >> v[i][0];

    for(int j = 1; pow * 2 <= N; ++j){ // pentru fiecare pas (putere a lui 2)
        for(int i = 0; i + pow * 2 - 1 < N; ++i) // incepand cu pozitia i
            v[i][j] = minim(v[i][j - 1], v[i + pow][j - 1]); // calculez minimul [i, i + 2 ^ j] = minim ( minim[i, 2^j-1], minim[i + 2^(j-1), i + 2^j])
        pow *= 2;
    }

    for(int i = 0; i < M; ++i){
        in >> st >> dr;
        pas = lg[dr - st + 1]; // 2^pas =  lungimea celui mai mare interval inclus in [st, dr] pentru care minimul este calculat =>  v[st][l] = minimul de la st la st + 2^l
        out << minim (v[st - 1][pas], v[dr - (1 << pas)][pas]) << '\n'; // minimul pentru [st, dr] este minimul dintre minimul pentru [st, st + 2^pas] si [dr - 2 ^ pas, dr]
    }
    return 0;
}