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...