Cod sursa(job #2467482)

Utilizator geniucosOncescu Costin geniucos Data 4 octombrie 2019 15:04:30
Problema Range minimum query Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include<bits/stdc++.h>

using namespace std;

template < class T, class F >
class RangeMinimumQuery {
public:
    RangeMinimumQuery (int _N, F *_f):
        N(_N), f (_f),
        table (1, vector < T > (N)) {}

    void setElement (int pos, T val) {
        table[0][pos] = val;
    }

    void setUp () {
        lg.resize (N + 1);
        lg[1] = 0;
        for (int i=2; i<=N; i++) {
            lg[i] = lg[i - 1];
            if ((2 << lg[i]) <= i)
                lg[i] ++;
        }
        table.resize (lg[N] + 1);
        for (int i=1; i<=lg[N]; i++) {
            table[i].reserve (N - (1 << i) + 1);
            for (int j=0; j + (1 << i) <= N; j++)
                table[i][j] = (*f) (table[i - 1][j], table[i - 1][j + (1 << (i - 1))]);
        }
    }

    T query (int left, int right) {
        int p = lg[right - left + 1];
        return f (table[p][left], table[p][right - (1 << p) + 1]);
    }
private:
    int N;
    vector < T > lg;
    vector < vector < T > > table;
    F *f;
};

int myMin (int a, int b) {
    if (a < b) return a;
    return b;
}

int main () {
    freopen ("rmq.in", "r", stdin);
    freopen ("rmq.out", "w", stdout);

    int N, M;
    scanf ("%d %d", &N, &M);
    RangeMinimumQuery < int, decltype(myMin) > rmq (N, &myMin);
    for (int i=0; i<N; i++) {
        int x;
        scanf ("%d", &x);
        rmq.setElement (i, x);
    }
    rmq.setUp ();
    while (M --) {
        int l, r;
        scanf ("%d %d", &l, &r);
        printf ("%d\n", rmq.query (--l, --r));
    }
    return 0;
}