Cod sursa(job #3151700)

Utilizator alexdumitruAlexandru Dumitru alexdumitru Data 22 septembrie 2023 17:09:58
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.32 kb
#include <fstream>

using namespace std;

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

const int NMAX = 1e5;
const int VMAX = 1e5;

int n, q;
int a[NMAX + 1], aib1[NMAX + 1], aib2[NMAX + 1];

int ub(int x){
    return x & (-x);
}

int my_min(int a, int b){
    return a < b ? a : b;
}

int query1(int x, int y){
    int res = VMAX;
    for(; x + ub(x) <= y; x += ub(x))
        res = my_min(res, aib2[x]);
    return my_min(res, a[x]);
}

int query2(int x, int y){
    int res = VMAX;
    for(; y - ub(y) >= x; y -= ub(y))
        res = my_min(res, aib1[y]);
    return res;
}

int query(int l, int r){
    return my_min(query1(l, r), query2(l, r));
}

void solve() {
    fin >> n >> q;
    for(int i = 1; i <= n; i++)
        aib1[i] = aib2[i] = VMAX;
    for(int i = 1; i <= n; i++){
        fin >> a[i];
        aib1[i] = my_min(aib1[i], a[i]);
        int next = i + ub(i);
        if(next <= n)
            aib1[next] = my_min(aib1[next], aib1[i]);
    }
    for(int i = n; i > 0; i--){
        aib2[i] = my_min(aib2[i], a[i]);
        int prev = i - ub(i);
        if(prev > 0)
            aib2[prev] = my_min(aib2[prev], aib2[i]);
    }
    while(q--){
        int l, r;
        fin >> l >> r;
        fout << query(l, r) << '\n';
    }
}

int main() {
    solve();
}