rmq ( range minimum / maximum query ) 問題是指:對於長度為 n 的數列 a,回答若干詢問 rmq (a , i , j ) ( i , j ≤ n),返回數列a中下標在 i , j 裡的最小(大)值,也就是說,rmq問題是指求區間最值的問題。
關於rmq問題,還是有很多方法來求解的(像線段樹啊什麼的),這裡主要介紹一下st演算法
要注意的是,st演算法只適用於靜態區間求最值,如果是動態的,那還是乖乖打線段樹吧
【基本思想】
st演算法它的本質相當於是動態規劃,下面我們以求最大值為例(最小值求法和最大值差不多)
我們用 f [ i ][ j ] 表示以 i 為起點,連續 2^j 個數中的最大值,例如 f [ 2 ][ 2 ] 就表示第 2 個數到第 5 個數的最大值
(1)預處理:
我們用a表示原序列,由於 = 1,按照 f 陣列的定義,f [ i ][ 0 ] 就等於 a[ 0 ](初始化)
對於每乙個 f 陣列表示的序列,我們都把它拆成兩部分,很明顯,它的最大值就是這兩部分的最大值中較大的那乙個
那麼轉移方程就是:f [ i ][ j ] = max ( 1 << j 是位運算,相當於2^j )
具體的**:
void rmq()
具體的**如下(log 陣列是預處理出來了的):
for(i=1;i<=詢問數;++i)
其實時間複雜度看**很容易可以分析出來
預處理部分:j 迴圈是o(log n),i 迴圈是o(n),總共是o(n * log n)
詢問部分:每次詢問的複雜度是o(1),有 q 個詢問就是o(q)
例題傳送門st表
裸的st模板啦,**如下:
#includeusing namespace std;
int n,m,a[100010],l,r,k,ans,f[100010][25],log[100010];
void rmq()//預處理
return 0;
}
RMQ演算法 ST表
題目大意就是給你兩個長度為n的序列讓你找到乙個盡可能大的下標p使得1 p之間的任意兩個區間l r都滿足rmq u,l,r 相等其實就是最小下標相同 rmq range minimum maximum query 問題是指 對於長度為n的數列a,回答若干詢問rmq a,i,j i,j n 返回數列a中...
RMQ的ST表演算法
rmq range minimum maximum query 即區間最值查詢,是指這樣乙個問題 對於長度為n的數列a,回答若干次詢問rmq i,j 返回數列a中下標在區間 i,j 中的最小 大值。本文介紹一種比較高效的st演算法解決這個問題。st sparse table 演算法可以在o nlog...
RMQ問題 ST演算法
rmq問題 rmq問題是指求區間最值的問題。rmq演算法 st演算法 時間複雜度 預處理o nlogn 查詢o 1 以求最大值為例,設d i,j 表示 i,i 2 j 1 這個區間內的最大值,那麼在詢問到 a,b 區間的最大值時答案就是max d a,k d b 2 k 1,k 其中k是滿足2 k ...