Cod sursa(job #1932223)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 19 martie 2017 16:32:08
Problema Range minimum query Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;
ifstream in("rmq.in");
ofstream out("rmq.out");

const int NMax = 1e5 + 5;
const int inf = 1e9;

// rezolvare cu O( sqrt(N) ) pe query

int N,M;
int v[NMax],mn[NMax];
// mn[i] - minimul pe a i-a bucata de sqrt(N) lungime
// (minimul pe intervalul [(i-1)*sqrt(N) + 1; i*sqrt(N)]

int main() {
    in>>N>>M;
    for (int i=1;i<=N;++i) {
        in>>v[i];
    }

    int root = (int)sqrt(N);

    // se construieste mn
    for (int i=1;i*root <= N;++i) {
        mn[i] = inf;
        int lim = i*root;
        for (int j = (i-1)*root + 1; j <= lim ;++j) {
            mn[i] = min(mn[i],v[j]);
        }
    }

    for (int i=1;i<=M;++i) {
        int a,b,drA,stB,j;
        in>>a>>b;
        int val = inf;

        for (j = 1;j*root < a;++j) ;

        drA = min(b,j*root);

        // se parcurg bucatile de sqrt(N) cuprinse intre a si b
        // care nu contin nici a, nici b
        ++j;
        while (j*root < b) {
            val = min(val,mn[j]);
            ++j;
        }
        stB = max(a,(j-1)*root + 1);

        // elementele ramase la stanga bucatilor de sqrt(N)
        for (int k=a;k<=drA;++k) {
            val = min(val,v[k]);
        }

        // elementele ramase la dreapta bucatilor de sqrt(N)
        for (int k=stB;k<=b;++k) {
            val = min(val,v[k]);
        }
        out<<val<<'\n';
    }

    return 0;
}