Pagini recente » Cod sursa (job #2411119) | Cod sursa (job #1047935) | Cod sursa (job #2398099) | Cod sursa (job #2633321) | Cod sursa (job #3037850)
#include<iostream>
#include<fstream>
using namespace std;
ifstream in("rmq.in");
ofstream out("rmq.out");
#define cin in
#define cout out
const int nmax = 100005;
const int L = 18;
int n, m;
int a[nmax];
int dp[nmax][L];
int logaritm[nmax];
// dp[i][j] - raspunsul minim pentru intervalul de lungime 2^j care incepe din i
int getMin(int l, int r) {
int lungimeInterval = r - l + 1;
int log = logaritm[lungimeInterval];
// pot sa impart intervalul l..r in doua subintervale:
// intervalul care incepe cu l si are lungimea 2 ^ log
// intervalul care incepe cu r - (2^log) + 1 si are lungimea 2 ^ log
return min(dp[l][log], dp[r - (1 << log) + 1][log]);
}
int main() {
logaritm[1] = 0;
for(int i = 2; i < nmax; ++i) {
logaritm[i] = logaritm[i / 2] + 1;
}
cin >> n >> m;
for(int i = 1; i <= n; ++i) {
cin >> a[i];
}
for(int i = 1; i <= n; ++i) {
dp[i][0] = a[i];
// raspunsul minim pe intervalul de lungime 2^0 care incepe din i este a[i]
}
for(int exp = 1; exp < L; exp++) {
for(int i = 1; i + (1 << exp) - 1 <= n; ++i) {
// intervalul de lungime 2^exp care incepe din i
// stiu ca intervalul asta are doua jumatati:
// un interval de lungime 2^(exp - 1) care incepe la i
// un interval de lungime 2^(exp - 1) care incepe in i + 2^(exp-1)
int halfLen = 1 << (exp - 1);
dp[i][exp] = min(dp[i][exp - 1], dp[i + halfLen][exp - 1]);
}
}
while(m--) {
int l, r;
cin >> l >> r;
cout << getMin(l, r) << '\n';
}
}