Cod sursa(job #2753374)

Utilizator MirunaStefaniaLupascu Miruna-Stefania MirunaStefania Data 22 mai 2021 17:27:53
Problema Range minimum query Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 kb

#include<bits/stdc++.h>
using namespace std;
ifstream fin("rmq.in");
ofstream fout("rmq.out");



int n, m;
int a[18][100003];; ///a[i][j] --> minimul pe o lungime de 2^i elem ce incepe de pe poz j

///RMQ

void initializare()
{
    int i, j, p;
    //din curs:
    //1 6 → min(min(1,4), min(3,6)) - prin urmare, putem face 2 query-uri
      for(i = 1, p = 2; p <= n; ++i, p *= 2)/// p--> nu are rost sa cautam mai multi parinti decat sunt in total noduri
        for(j = 0; j < n; ++j)
         a[i][j] = min(a[i-1][j], a[i-1][j + p/2]);///"concatenam" cate 2 intervale si le facem minimul pe reuniune

}

int calc(int x, int y)
{
    //calculam lungimea intervalului
    int lg = x - y + 1;
    ///cautam cea mai mare putere a lui 2 apropiata de lg
    int pow = 1, i = 0;
    while(pow*2 < lg)
        {
            pow *= 2;
            i++;    ///exponentul puterii de 2
        }

    ///acum stim ca putem sa sarim: peste o bucata de interval
    ///fiind minim intervalele se pot intrepatrunde
    return min(a[i][x], a[i][y-pow+1]);
    ///in a[i][x] ---> cel mai mic elem din bucata de vector ce incepe pe poz x si are lg = 2^i
    ///a[i][y-pow+1] ....
    ///am imbunatatit cautarea

}

int main()
{
     int x, y, i, j;
    fin >> n >> m;
    ///initializam matriea de min
     for( i=0; i<17; ++i)
        for(j=0; j<100000; ++j)
            a[i][j]=100005; //o valoare foarte mare nu va influenta minimul

    for(j = 0; j < n; ++j)
        fin>>a[0][j]; //elem minime pe o lungime de 2^0

    initializare();

    for( i = 1; i <= m; ++i)
    {
        fin >> x >> y; //cel mai mic elem pe intervalul [x, y]
        fout << calc(x-1, y-1) << "\n";///indexare de la 0
    }

}