Cod sursa(job #2292024)

Utilizator maria15Maria Dinca maria15 Data 28 noiembrie 2018 21:25:22
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <fstream>

using namespace std;

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

int n, m, d[18][100001], log[100001], sub, lsub, i, t, j, a, b, interval;

int main(){
    /// la fiecare query, determin lungimea intervalului in care trebuie sa caut minimul
    /// gasesc cea mai mare putere de 2 mai mica decat acea lungime
    /// aceasta e mai mare sau egala cu jumatate din lungimea intervalului
    /// deci, daca iau doua secvente de lungime egala cu puterea respectiva,
    /// una pornind de la inceputul intervalului si cealalta, de la final,
    /// voi acoperi cu siguranta tot intervalul din query
    /// aflu minimul din cele doua subsecvente
    /// si minimul dintre ele => solutia :)


    /// precalculez partea intreaga a logaritmului fiecarui interval posibil

    log[1] = 0;
    for(i=2;i<=100000;i++)
        log[i] = log[i/2] + 1;

    fin>>n>>m;
    for(i=1;i<=n;i++)
        fin>>d[0][i];

    /// d[i][j] = minimul din secventa ce incepe pe pozitia j si are lungimea 2 la i
    /// calculez toate elementele din d
    for(i=1;i<=log[n]+1;i++){
        t = (1<<i);
        for(j=1;j<=n;j++){
            d[i][j] = d[i-1][j];
            if(t/2 + j <= n)
                d[i][j] = min(d[i][j], d[i-1][t/2 + j]);
        }
    }


    /// trecem la query-uri
    while(m--){
        fin>>a>>b;
        interval = b-a+1;
        sub = log[interval];
        lsub = (1<<sub);
        fout<<min(d[sub][a], d[sub][b-lsub+1])<<"\n";
    }
    return 0;
}