Pagini recente » Cod sursa (job #1030097) | Cod sursa (job #7541) | Cod sursa (job #2218476) | Cod sursa (job #2369477) | Cod sursa (job #3253689)
#include <bits/stdc++.h>
using namespace std;
const int MAXP = 20, NMAX = 100001;
int rmq[MAXP][NMAX], Log[NMAX];
void precalcMinims(int n){
for(int put = 1; (1 << put) <= n; put++){
for(int i = 1; i <= n;i++){
rmq[put][i] = rmq[put-1][i];
int right = i + (1<<(put-1));
/// minimul este minimul dintre diagonala ori la urmatoarea secventa putere de doi anterioara
if(right <= n && rmq[put-1][right] < rmq[put][i]){
rmq[put][i] = rmq[put-1][right];
}
}
}
/// putem calcula exponentii direct din precalculare pentru a ne fi mult mai usor sa computam rezultatul si a nu mai folosii cautare binara
for(int i = 2;i <= n;i++){
Log[i] = Log[i / 2] + 1;
}
}
int32_t getMinim(int left, int right){
/// trebuie sa incadram intervalul nostru intre doua puteri, doua intervale de puteri de 2 de aceea ne si trebuie
/// calculat exponentul
int exponent = Log[right - left + 1];
int lenght = (1 << exponent);
return min(rmq[exponent][left], rmq[exponent][right - lenght + 1]);
}
int32_t main(void){
ofstream cout("rmq.out");
ifstream cin("rmq.in");
int n, Q;
cin >> n >> Q;
for(int i = 1;i <= n;i++){
cin >> rmq[0][i]; /// practic minimul pentru secventa de 2 ^ 0 = 1 este fix el insusi astfel ne putem permite\
// al initializa direct din citire
}
/// !! precalculam
precalcMinims(n);
/// Querys
while(Q--){
int st, dr;
cin >> st >> dr;
cout << getMinim(st, dr) << '\n';
}
}