RMQ problem (ST algorithm)

RMQ ask questions is maximum or minimum within a certain interval, ST algorithm can solve the problem .ST RMQ algorithm is commonly used in a number of questions to ask several times for a range, compared to a tree line, its program to achieve more simple, run faster, it can be done O (nlogn) pretreatment, O (1) to answer each question. conditions of use ST algorithm is not modified operation, so it is suitable for the operation and did not modify the number of visits more (10 ^ 6 level or greater) situation.

1. Pretreatment

ST principle of dynamic programming algorithm actually is, we must first know the meaning of the array f, f [i] [j] represents the left end in i, j represents 2 ^ j length, so f [i, j] represents the range of [i, i + 2 ^ j -1] a maximum value within this range, it is a [i] starting from a maximum continuous number of 2 ^ j. Since the number of elements of two 2 ^ j, so that average the middle into two parts, each part are the number 2 ^ (j-1); Suppose f [6] [3] into f [6] [2] and f [10] [2], as shown below , the
RMQ problem (ST algorithm)
maximum value of the entire interval must be larger maximum left and right parts, to satisfy the principle of dynamic programming optimization analyzes have f array state transition equation is f [i] [j] = max (f [i ] [j-1], f [i + 2 ^ (j-1)] [j-1]).

for(int j = 1;(1<<j) <= n;++j) //j枚举每一个可能出现的长度 
    for(int i = 1;i + (1<<j)-1 <= n;i++)  //i枚举每一个区间的左端点 
    f[i][j] = max(f[i][j-1],f[i+(1<<(j-1))][j-1]);

2. Ask

when the maximum value to be accessed interval [L, R], it is necessary to know the length len interval, mn is stored in the array equal to a length len is less than the maximum power of 2, to access the interval [5,10] the maximum value, the first calculated value men [len], then the interval [5,10] = [5,8] U [7,10].
RMQ problem (ST algorithm)

Code

//对于一定长度的区间len,mn[len]表示小于等于len的最大的2的幂次 
   for(int len = 1;len <= n;++len)
   {
     int k = 0;
     while(1<<(k+1) <= len)
     k++;
     mn[len] = k;
   }

3. find the interval [x, y] maximum

int k = mn[R - L + 1];
ans = max(f[L][k],f[R-(1<<k)+1][k]);

Code


#include<iostream>
using namespace std;
const int maxn=1e6+5; 
int f[maxn][25];
int mn[maxn];
int a[maxn];
int m,n;
void rmq_init()
{
  //初始化所有长度为1的区间的最大值 
  for(int i = 1;i <= n;i++)    
  f[i][0] = a[i];

  for(int j = 1;(1<<j) <= n;++j) //j枚举每一个可能出现的长度 
    for(int i = 1;i + (1<<j)-1 <= n;i++)  //i枚举每一个区间的左端点 
    f[i][j] = max(f[i][j-1],f[i+(1<<(j-1))][j-1]);

  //对于一定长度的区间len,mn[len]表示小于等于len的最大的2的幂次 
   for(int len = 1;len <= n;++len)
   {
     int k = 0;
     while(1<<(k+1) <= len)
     k++;
     mn[len] = k;
   }
}
 int rmq(int L,int R)
{
   int s = mn[R-L+1];
  int ans = max(f[L][s],f[R - (1<<s) + 1][s]);
  return ans;
 }
int main()
{
  cin>>n;
  for(int i = 1;i <= n;i++)
  cin>>a[i];
  rmq_init();
  int L,R;
  cin>>m;
  for(int i = 1;i <= m;i++)
  {
    cin>>L>>R;
    cout<<rmq(L,R)<<endl;
  }
  return 0;
 }

Screenshot results
RMQ problem (ST algorithm)

Guess you like

Origin blog.51cto.com/14472348/2468297