RMQ
RMQ
• Given a sequence of n integers a0,. . ., an-1. We denote rmq(i, j) the minimum element of the sequence ai,
ai+1, . . ., aj. Given m pairs (i1, j1),. . ., (im, jm), compute the sum Q = rmq(i1, j1) + . . . + rmq(im, jm)
• Input
• Line 1: contains an integer n (1 <= n <= 106)
• Line 2: contains a0, . . . , an-1 ( 1 <= ai <= 106)
• Line 3: contains m (1 <= m <= 106)
• Line k+3 (k = 1, . . ., m): contains ik, jk (0 <= ik < jk < n)
• Output
• Write the value Q
Range Minimum Query
• Example
stdin stdout
16 6
2461687335891264
4
15
09
1 15
6 10
Hint
• Denote M[j, i] the index of the smallest element of a[i], a[i+2],…, a[i+2j -1] (the sequence from index i and has
the length 2j).
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2 4 6 1 6 8 7 3 3 5 8 9 1 2 6 4
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 0 1 3 3 4 6 7 8 8 9 10 12 12 13 15 -
2 3 3 3 3 7 8 8 8 8 12 12 12 12 - - -
3 3 3 3 3 8 12 12 12 12 - - - - - - -
4 12 - - - - - - - - - - - - - - -
Hint
• M[0,i] = i, i = 0,…, N-1
• Recurrence relation:
• M[j,i] = M[j-1,i] if a[M[j-1,i]] < a[M[j-1,i+2j-1]
M[j-1,i+2j-1], otherwise
i i+2j-1 -1
i + 2j-1 i + 2j - 1
M[j, i]
Hint
• Query RMQ(i,j): the index of the smallest element of the sequence a[i], a[i+1], . . ., a[j]
• k = [log(j-i+1)]
• RMQ(i,j) = M[k,i] if a[M[k,i]] ≤ a[M[k, j-2k+1]]
M[k, j-2k+1]], otherwise
• RMQ(4,14) = ?
• k = [log(14-4+1)]=3
• a[7] > a[12] RMQ(4,14) = 12
M[3,7] = 12
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2 4 6 1 6 8 7 3 3 5 8 9 1 2 6 4
M[3,4] = 7
Implementation
#include <bits/stdc++.h>
int n;
int M[30][1000000];
int A[1000000];
void preprocessing(){
if(A[M[j-1][i]] < A[M[j-1][i+(1 << (j-1))]]) M[j][i] = M[j-1][i]; else M[j][i] = M[j-1][i + (1 <<
(j-1))];
}
Implementation
int k = log2(j-i+1);
return M[k][i];
}else{
return M[k][j-p2k+1];
}
Implementation
int main(){
scanf("%d",&n);
preprocessing();
scanf("%d",&m);
ans += A[rmq(I,J)];
return 0;