Pagini recente » Cod sursa (job #317951) | Cod sursa (job #2013662) | Cod sursa (job #1415628) | Cod sursa (job #3154790) | Cod sursa (job #2635244)
#include <fstream>
#define N 100000
using namespace std;
static const int b = 30;
int n, v[N], seg[b+1][N], mask[N];
int cmp (int a, int b) {
return v[a] < v[b] ? a : b;
}
int log (int x) {
return 31 - __builtin_clz(x);
}
int trans (int x, int base = b) {
return x - (log(mask[x] & ((1 << base) - 1)));
}
int query (int x, int y) {
if (y - x + 1 <= b)
return v[trans(y, y-x+1)];
int ans = cmp(trans(x + b - 1), trans(y));
x /= b; ++x;
y /= b; --y;
if (x <= y) {
int lg = log(y-x+1);
ans = cmp(ans, cmp(seg[lg][x], seg[lg][y - (1<<lg) + 1]));
}
return v[ans];
}
int main (void) {
ifstream fin ("rmq.in");
ofstream fout ("rmq.out");
int n, m, i;
fin >> n >> m;
for (i=0; i<n; ++i)
fin >> v[i];
int at = 0;
for (i=0; i<n; ++i) {
at = (at << 1) & ((1<<b) - 1);
while (at && cmp(i, i - __builtin_ctz(at)) == i)
at ^= at & -at;
at |= 1;
mask[i] = at;
}
n/=b;
for (i=0; i<n; ++i)
seg[0][i] = trans(b*i + b - 1);
int j;
for (j=1; (1<<j) <= n; ++j)
for (i=0; i + (1<<j) <= n; ++i)
seg[j][i] = cmp(seg[j-1][i], seg[j-1][i + (1<<j-1)]);
int x, y;
for (; m; --m) {
fin >> x >> y;
--x;
--y;
fout << query(x, y) << '\n';
}
return 0;
}