#include <bits/stdc++.h>
using namespace std;
/**
a = a1 ... a100
min{[10, 60]} = min([10, 41], [42, 57], [58, 59], [60,60])
51 = 32 + 16 + 2 + 2^0
min([10, 41], [26, 57])
32 (2^5) < 51
2^5 = 32
------------------------------
7 2^4 7+32-1 = 38
22 23
32 = 2^4 + 2^4
rmq[5][7] = min(rmq[4][7], rmq[4][23])
[7,22] [23, 38]
rmq[i][j] = min(rmq[i-1][j], rmq[i-1][j+2^(i-1)])
[j, j+2^(i-1)-1] [j+2^(i-1), j+2^i-1]
a = a1 a2 ... a18
i = 3; j = 1, 2, ..., 11
i = 4; j = 1, 2, 3
1 5 6 4 3
5 6 4 = [2,3] si [3, 4]
| len |
x ................................ y
| len |
j = e[y-x+1]
len = 16
rmq[j][x], rmq[j][y-len+1]
rmq[i][j] = valoarea minima din intervalul [j, j+2^i-1]
Date initiale
rmq[0][i] = a[i], i=1..n
rmq[1][1] = min(a[1], a[2]) = min(rmq[0][1], rmq[0][2])
rmq[i][j] = min(rmq[i-1][j], rmq[i-1][j+2^(i-1)])
[j,j+2^(i-1)-1] [j+2^(i-1),j+2^i-1]
Vrem sa stim:
1. pentru un i, cat este 2^i
2. Pentru un interval de lungime x, care este exponentul maxim e
cu prop. ca 2^e <= x
(Pentru 2. construim vectorul e cu 2^e[i] <= i)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
e = 0 1 1 2 2 2 2 3 3 3 3 3 3 3 3 4
*/
ifstream fin("rmq.in");
ofstream fout("rmq.out");
int n, m;
int rmq[18][100003];
int e[100003], L[20];
/// L[i] = 2^i
int main()
{
int i, j, x, y, len;
/// construim pe L
L[0] = 1;
for (i = 1; i <= 18; i++)
L[i] = L[i - 1] * 2;
/// construim e
e[1] = 0;
for (i = 2; i <= 100000; i++)
e[i] = 1 + e[i / 2];
fin >> n >> m;
for (i = 1; i <= n; i++)
fin >> rmq[0][i]; /// fin >> a[i]
/// recurentele:
for (i = 1; i <= e[n]; i++)
{
for (j = 1; j <= n - L[i] + 1; j++)
rmq[i][j] = min(rmq[i-1][j], rmq[i-1][j+L[i-1]]);
}
for (i = 1; i <= m; i++)
{
fin >> x >> y;
j = e[y - x + 1];
len = L[j];
fout << min(rmq[j][x], rmq[j][y - len + 1]) << "\n";
}
return 0;
}