Cod sursa(job #3364425)

Utilizator Andrei-Dani-10Pisla Andrei Daniel Andrei-Dani-10 Data 3 septembrie 2026 10:14:43
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.47 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int nmax = 1e5, lgmax = 17;
int n, nrq, xx, yy; vector <int> a;

struct rmq_divide{

    vector <int> rmq[lgmax + 2]; int msb[(1 << lgmax) - 1];

    void build(vector <int> &arry){
        rmq[0] = arry; int sz = arry.size(); 

        msb[0] = -1; /// compute msb
        for(int i = 1; i <= (1 << lgmax) - 1; i++){
            msb[i] = 1 + msb[i >> 1];
        }; msb[0] = 0;

        for(int p = 1; (1 << p) <= sz; p++){
            int length = (1 << (p + 1)); rmq[p] = arry;
            
            int st = 0, mij, dr = length - 1;
            for(; st + (1 << p) < sz; st += length, dr += length){
                mij = (st + dr) >> 1; dr = min(dr, sz - 1); 
                for(int i = mij - 1; i >= st; i--){ /// range [st, mij]
                    rmq[p][i] = min(rmq[p][i], rmq[p][i + 1]);
                }
                for(int i = mij + 2; i <= dr; i++){ /// range [mij + 1, dr]
                    rmq[p][i] = min(rmq[p][i], rmq[p][i - 1]);
                }
                
            }; 
        }

        return;
    }

    int query(int st, int dr){
        int e = msb[st ^ dr]; 
        return min(rmq[e][st], rmq[e][dr]);
    }
} rmq;

int main(){

    in>>n>>nrq; a.resize(n);
    for(auto &xx : a){
        in>>xx;
    }

    rmq.build(a);

    for(; nrq > 0; nrq--){
        in>>xx>>yy;
        out<<rmq.query(xx - 1, yy - 1)<<"\n";
    }

    return 0;
}