RMQ的ST寫法和線段樹寫法兩種姿勢

2021-06-19 02:51:02 字數 1344 閱讀 1384

rmq問題為求區間最值的問題

線段樹可以在o(logn)的時間複雜度內完成詢問操作。

但是st演算法可以在常數時間內完成詢問操作

st演算法:基於動態規劃求區間最值的演算法。

分為預處理和查詢兩部分

預處理:定義 f[i][j] 為從 i開始到 i+2^j-1 區間內的最值 , 我們可以講這段2^j的區間分成兩部分長度都為2^(j-1)的相同區間

區間1 為  i.....i+2^(j-1)-1   區間2為  i+2^(j-1).....i+2^j-1

那麼可以得到  f[i][j] =max( f[i][j-1],f[i+2^(j-1)][j-1],邊界條件為f[i][0]=a[i].

由於大的區間是由小的區間得到的,所以預處理時必須按區間長度遞增的順序遞推出f[i][j].

查詢:求區間[ i , j ]的最值   令 d=(int) log2( j-i+1)   

我們取靠i的長度為2^d區間 以及靠j的2^d區間內的最大值 ,兩個區間內可以存在公共部分

則i,j max= max ( f[i][d] ,f[j-2^d+1,d])

題意:要求找出區間內的最大最小值的差。

用兩個陣列分別儲存區間最大和最小值

詳細**如下:

#include#include#include#define lson l,m,p<<1

#define rson m+1,r,p<<1|1

#define max(a,b) (a>1;

if(l==r)

if(k<=m)

update(val,k,lson);

else

update(val,k,rson);

maxp[p]=max(maxp[p<<1],maxp[p<<1|1]);

minp[p]=min(minp[p<<1],minp[p<<1|1]);

}void query(int l,int r,int l,int r,int p)

if(l<=m)

query(l,r,lson);

if(r>=m+1)

query(l,r,rson);

}int main()

for(i=1;i<=m;i++)

return 0;

}st(動態規劃)*/

int n,m;

int a[50001];

int fmin[50001][20],fmax[50001][20];

void init(){

int i,j;

for(i=1;i<=n;i++)

fmin[i][0]=fmax[i][0]=a[i];

for(i=1;(1<

RMQ問題 st 線段樹

j 演算法 rmq range minimum maximum query 問題是指 對於長度為n的數列a,回答若干詢問rmq a,i,j i,j n 返回數列a中下標在 i,j 裡的最小 大 值,也就是說,rmq問題是指求區間最值的問題 主要方法及複雜度 處理複雜度和查詢複雜度 如下 1.樸素 即...

RMQ問題 線段樹演算法,ST演算法優化

對於長度為n的數列a,回答若干詢問rmq a,i,j i,j n 返回數列a中下標在 i,j 裡的最小 大 值,也就是說,rmq問題是指求區間最值的問題 主要方法及複雜度 處理複雜度和查詢複雜度 如下 1.樸素 即搜尋 o n o n 2.線段樹 segment tree o n o qlogn 3...

RMQ問題 線段樹演算法,ST演算法優化

對於長度為n的數列a,回答若干詢問rmq a,i,j i,j n 返回數列a中下標在 i,j 裡的最小 大 值,也就是說,rmq問題是指求區間最值的問題 主要方法及複雜度 處理複雜度和查詢複雜度 如下 1.樸素 即搜尋 o n o n 2.線段樹 segment tree o n o qlogn 3...