RMQ problem (range max problem range minimum/maximum Query)
St algorithm
RMQ (range minimum/maximum query), or interval-most-valued queries, refers to the question of answering a number of queries RMQ (A,I,J) (I, j<=n) for sequence A of length n, and returning the minimum/large value of the column A in the middle of the i,j. If there is only one query, then only one time for the for can be done, but if there are many times the inquiry will not be able to be processed in a very fast. An online algorithm is presented here. The so-called online algorithm, refers to the user each input a query immediately processing a query. The algorithm is usually used for a long time to preprocess, waiting for sufficient information can be used in less time to answer each query. The ST (Sparse Table) algorithm is a well-known algorithm for online processing of RMQ problems, which can be preprocessed in O (nlogn) time and then answer each query in O (1) time.
Suppose that the A array is:
1, 3, 6, 7, 4, 2, 5
1. Preprocessing
Set DP[I][J] Indicates the maximum number of consecutive 2^j from the first bit. For example, Dp[2][1] is the maximum of 2 consecutive numbers for the 2nd digit, which is the maximum value between 6 and 4, which is mn[2][1] = 4. We first initialize dp[0...n-1][0] to the value in the a array, and then we can easily think of the recursive equation:
DP[I][J] = max (dp[i][j-1], dp[i + (1 << j-1)][j-1])
20000> 2**14 > 10000
30000> 2**15 > 40000
60000> 2**16 > 70000
1for (int0; j + +)2for (int 1; i + (11; i + +)3 1], Dp[i + (11 1]);
2. Enquiry
Suppose we need to query the maximum value between [Lo, hi], we make k = log2 (hi-lo+1)
Since K is log2 (hi-lo+1) is rounded down, it cannot completely cover lo to hi
Just make sure Lo + K is longer than 1/2 of the length of lo to hi: Rmq[l, r] = min (dp[l][k], Dp[r-(1 << k) + 1][k]);
Because it is not difficult to see, for any length len, (int) log2 (len) * * 2 > LEN/2
So the final code is as follows:
1#include <cstdio>2#include <algorithm>3#include <cstring>4#include <cmath>5 using namespacestd;6 /*7 20000> 2**14 > 100008 30000> 2**15 > 400009 60000> 2**16 > 70000Ten */ One intn[10007]; A - intmx[10007][ the]; - the intMain () - { - intn,q; -scanf"%d", &n); + for(intI=0; i<n;i++) - { +scanf"%d", &n[i]); A } at // ------------------------------- - -memset (MX,0,sizeof(MX)); - for(intI=0; i<n;i++) - { -mx[i][0] =N[i]; in } - to for(intI=1;i< the; i++) + { - for(intj=0; j+ (1<<i)-1<n;j++) the { *Mx[j][i] = max (mx[j][i-1], mx[j+ (1<<i-1)][i-1]); $ }Panax Notoginseng } - the // ------------------------------- +scanf"%d", &q); A intlo, hi; the for(intI=0; i<q;i++) + { -scanf"%d%d", &lo, &hi); $ intK = (int) log2 (Double) (hi-lo+1)); $ intans = max (mx[lo][k], mx[hi-(1<<K) +1][k]); -printf"%d\n", ans); - } the}
Of course, you can also use line tree to solve
51nod1174 interval Maximum number && RMQ problem (ST algorithm)