溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

RMQ問題(ST算法)

發布時間:2020-04-27 13:05:33 來源:網絡 閱讀:325 作者:wx5d3c7e0ad6c30 欄目:編程語言

RMQ是詢問某個區間內的最大值或最小值的問題,ST算法可以求解RMQ問題.ST算法通常用在要 多次詢問某一些區間的問題中,相比于線段樹,它的程序實現更加簡單,運行速度更快,它可以做到O(nlogn)的預處理,O(1)回答每個問題.使用ST算法的條件是沒有修改操作,因此它適用于沒有修改操作并且訪問次數較多(10^6級別甚至更大)的情況.

1.預處理

ST算法的原理實際上是動態規劃,首先要知道f數組的含義,f[i][j]中i表示左邊端點,j表示2^j個長度, 因此f[i,j]表示的是區間為[i,i+2^j-1]這個范圍內的最大值,也就是以a[i]為起點連續的2^j個數的最大值.由于元素個數為2^j個,所以從中間平均分成兩部分,每一部分的個數都為2^(j-1);假設f[6][3]分為f[6][2]和f[10][2],如下圖所示,
RMQ問題(ST算法)
整個區間的最大值一定是左右兩部分最大值的較大者,滿足動態規劃的最優化原理,分析得f數組的狀態轉移方程為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.詢問

當要訪問區間[L,R]的最大值,需要知道區間的長度len,mn數組存放的是小于等于一定長度len的最大的2的冪次,若要訪問區間[5,10]的最大值,則要先計算出men[len]的值,那么區間[5,10]=[5,8]U[7,10].
RMQ問題(ST算法)

代碼實現

//對于一定長度的區間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.求區間[x,y]最大值

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

代碼實現


#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;
 }

結果截圖
RMQ問題(ST算法)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女