RMQ algorithm, rmq
I. Overview
RMQ (Range Minimum/Maximum Query), that is, the Maximum Range Query, refers to A question: For Series A with n length, answer A number of questions RMQ (A, I, j) (I, j <= n), returns the smallest/least between I and j in sequence. These two problems are frequently encountered in practical applications. Next we will introduce a more efficient algorithm to solve these two problems. Of course, this problem can also be solved using the line segment tree (also called the Interval Tree). The algorithm complexity is: O (N )~ O (logN), which is not introduced here
Ii. algorithm ideas
1. Use dp to pre-process the maximum value of 2 ^ j Starting from point I, and split it into two segments during dp.
2. query the maximum value of the Left endpoint starting with I and the end point starting with j.
A very good blog http://blog.csdn.net/liang5630/article/details/7917702
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <cmath> 5 using namespace std; 6 int a [2000001]; 7 int minn [2000001] [15]; 8 int fastpow (int a, int p) 9 {10 int base = a; 11 int ans = 1; 12 while (p) 13 {14 if (p % 2) ans * = base; 15 base * = base; 16 p/= 2; 17} 18 return ans; 19} 20 int main () 21 {22 int n, m; 23 scanf ("% d", & n, & m); 24 for (int I = 0; I <= n; I ++) 25 for (int j = 0; j <= 14; j ++) 26 minn [I] [j] = 0x7ff; 27 for (int I = 1; I <= n; I ++) 28 scanf ("% d", & minn [I] [0]); // The point that can be reached in step 1 of point I is itself 29 for (int j = 0; j <= 14; j ++) // 2 ^ j 30 {31 for (int I = 1; I <= n; I ++) // Based on the no-aftereffect of dp, under certain conditions of j, it is necessary to process the positions that can be reached after each point jump to 32 {33 if (I + (1 <j)-1 <= n) // The second interval shall be within the range of 34 minn [I] [j] = min (minn [I] [J-1], minn [I + (1 <(J-1)] [j]); 35} 36} 37 // tri-Section I -- I + 2 ^ (J-1) -1 -- I + 2 ^ J-1 38 printf ("0 \ n"); 39 int k = log (m)/log (2 ); // ensure that the length of the value range is within the required range: 40 // take the I-m to i41 for (int I = 2; I <= n; I ++) 42 {43 printf ("% d \ n", min (minn [I-m] [k], minn [I-fastpow (2, k) + 1] [k]); 44 // left endpoint right endpoint 45} 46 return 0; 47}