Cod sursa(job #1773060)

Utilizator danielNiculaeDaniel Niculae danielNiculae Data 7 octombrie 2016 15:02:16
Problema Range minimum query Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include "algorithm"
#include "fstream"

using namespace std;

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

const int INF = 1000000005;
const int NMAX = 100005;
const int LOG_NMAX = 19;

int N, M;

int rmq[LOG_NMAX][NMAX];


int extractMinimum(int x, int y, int i, int j) {
//    fout << "i: " << i << ", j: " << j << ", x: " << x << ", y: " << y << "\n";
    if(x <= (j - 1)*(1<<i) + 1 && j*(1<<i) <= y) {
        return rmq[i][j];
    }

    int left = INF, right = INF;
    if(x <= (2*j-1)*(1<<(i - 1))) {
        left = extractMinimum(x, y, i - 1, 2*j - 1);
    }
    if((2*j-1)*(1<<(i - 1)) + 1 <= y) {
        right = extractMinimum(x, y, i - 1, 2*j);
    }
    return min(left, right);
}

int nonZeroMin(int a, int b) {
    if(!a) {
        return b;
    }
    if(!b) {
        return a;
    }
    return min(a, b);
}

int main() {

    fin >> N >> M;
    int depth = 0;

    for(int j = 1 ; j <= N ; j++) {
        fin >> rmq[0][j];
    }

    for(int i = 1 ; (1 << (i-1)) <= N ; i++) {
        depth++;
        for(int j = 1 ; (j-1) * (1 << i) < N ; j++) {
//            printf("Computing rmq of i: %d, j: %d\n", i, j);
            rmq[i][j] = nonZeroMin(rmq[i - 1][(j - 1) * 2 + 1], rmq[i - 1][j*2]);
        }
    }

//    for(int i = 0 ; i <= 3 ; i++) {
//        for(int j = 1 ; j <= N ; j++) {
//            fout << rmq[i][j] << " ";
//        }
//        fout << "\n";
//    }
//    fout << "\n";
//    fout.flush();

    for(int k = 1 ; k <= M ; k++) {
        int x, y;
        fin >> x >> y;
        fout << extractMinimum(x, y, depth, 1) << "\n";
    }
}