Cod sursa(job #2749368)

Utilizator ionut31Ioan Ionescu ionut31 Data 6 mai 2021 15:28:28
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb

#include <iostream>
#include <fstream>

using namespace std;

ifstream fin("rmq.in");
ofstream fout("rmq.out");

int N, M, Log2[100002],m[20][100002];

//subprogram pentru generarea matricei ce contine pe fiecare linie i
//minimele pe intervale de 2^i din sirul de numere dat si vectorul Log2 ce contine
//log2 din fiecare numar de la 1 la N
void sol()
{
    //Log2[0] = Log2[1] = 0;

    //calculam log2 din toate numerele de la 1 la N
    for (int i = 2; i <= N; ++i)
        Log2[i] = Log2[i/2] + 1;

    for (int i = 1; i <= Log2[N]; ++i)
        for (int j = 1; j + (1 << i) - 1 <= N; ++j)
            m[i][j] = min(m[i - 1][j], m[i - 1][j + (1 << (i - 1))]); //valoarea minima dintre minimul din prima juatate
            //si minimul din a doua jumatate
}

int main()
{
    fin >> N >> M;
    //completam prima linie a matricei(linia 0) cu sirul dat(minimele pe intervale de forma [i,i])
    for (int i = 1; i <= N; ++i)
        fin >> m[0][i];
    sol();

    for (int i = 1; i <= M; ++i)
    {
        int s, d, x;
        fin >> s >> d; //citim capetele intervalului din care trebuie afisata valoarea minima
        x = Log2[d - s + 1]; //x primeste valoarea log2 din lungimea intervalului ce are capetele s si d (ne pozitionam pe linia
        // potrivita in matricea m)

        //afisam cea mai mica valoare dintre minimele celor doua intervale de lungime x, intervale incluse
        // in intervalul [s,d] si care acopera tot intervalul [s,d]
        fout << min( m[x][s], m[x][d - (1 << x) + 1] ) << '\n';
    }

    return 0;
}