Pagini recente » Cod sursa (job #791348) | Cod sursa (job #1296688) | Cod sursa (job #670549) | Cod sursa (job #2000320) | Cod sursa (job #2753433)
#include <iostream>
using namespace std;
const int nMax = 100005;
int v[nMax][17], log2[nMax];
int main() {
freopen("rmq.in", "r", stdin);
freopen("rmq.out", "w", stdout);
// Input rapid
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
// Calculeaza toate valorile pentru log2(x) cu x in [1, nMax] - in O(nMax) (nu afecteaza complexitatea, din moment
// ce construirea array-ului are complexitatea O(n logn) si trebuie sa mearga si cand n=nMax)
log2[1] = 0;
for (int i = 2; i <= nMax; i++) {
log2[i] = log2[i / 2] + 1;
}
// Citeste toate numerele si pune-le in casuta 0 (ce semnifica faptul ca pentru urmatoarele 2^0=1 element,
// minimul este x = numarul citit)
for (int i = 1; i <= n; i++) {
cin >> v[i][0];
}
// Parcurge numarul de salturi exponentiale posibile
for (int p = 1; (1 << p) < n; p++) {
// Parcurge toate numerele de la indecsii de la care se pot sari 2^p elemente
for (int i = 1; i + (1 << p) - 1 <= n; i++) {
// Urmatoarele 2^p elemente au minimul min(min din prima jumatate, min din a doua jumatate)
v[i][p] = min(v[i][p - 1], v[i + (1 << (p - 1))][p - 1]);
}
}
int st, dr;
for (int q = 0; q < m; q++) {
cin >> st >> dr;
// Cate elemente sunt in intervalul [st, dr], in care trebuie cautat minimul
int nr = dr - st + 1;
// Minimul din intervalul [st, dr] este egal cu minimul dintre minimul intervalului [st, 2^(max posibil)] si
// [dr - 2^(max posibil) + 1, dr].
//
// A trebuit pus +1 pentru ca [2, 7] trebuie impartit in [2, 6] si [4, 7] (cand puterea maxima este 4),
// nu [2, 4] si [3, 6] (ar fi uitat ultimul numar) - din moment ce in intervalul [a, b] sunt b-a+1 numere
cout << min(v[st][log2[nr]], v[dr - (1 << log2[nr]) + 1][log2[nr]]) << "\n";
}
}