RMQ問題之ST演算法

2022-05-17 21:08:40 字數 1284 閱讀 6430

rmq問題:求長度為n的數列中,求[i,j]直接的最值。

st演算法:一種動態規劃的方法。

一、預處理dp陣列

對於區間[i,i+2^j-1]的最值,只需要知道區間[i,i+2^(j-1)-1]和區間[i+2^(j-1),i+2^j-1]的最值即可。

由此可的遞推方程:dp[i,i+2^j-1] = max(dp[i,i+2^(j-1)-1],dp[i+2^(j-1),i+2^j-1])

但是對於乙個比較長的數列,2^j是乙個非常大的數,我們也可發現,沒什麼必要直接記錄左右端點。

優化為i記錄乙個起點,j記錄類似距離的東西,dp[i,j]表示區間[i,i+2^j-1]。

優化後遞推方程:dp[i,j] = max(dp[i,j-1],dp[i+2^(j-1),j-1])

預處理dp陣列時間複雜度為o(nlogn)。

二、查詢最值

所以開始把乙個區間當dp陣列求出來,再進行查詢即可。

但是查詢時候,知道的是兩個端點l,r。

對於區間[l,r],如何再dp陣列中查詢呢?

前面講了i表示起點,j代表類似距離的東西。

很明顯l就是i了。可是2^j-1不可能是r,這時候就要找個中間的"j"了。

令len = r-l+1, 則2^k <= len(此處注意不是2^k-1,反證:當2^k-1 == len時,l + 2^k-1 = l + len = r + 1 > r)

即[l,r] = max(dp[l,k],dp[r-(2^k)+1,k])

查詢時間複雜度為o(1)。

儘管**比較簡潔並且功能比較強大,速度也比較快,可是並沒有線段樹那麼功能多。

1 #include 2 #include 3 #include 4

using

namespace

std;

5const

int maxn = 100005;6

int ma[maxn][20];7

int mi[maxn][20];8

inta[maxn];

9void init(int

n)17}18

int rmq_max(int l, int r, int

k)21

int rmq_min(int l, int r, int

k)24

int rmq(int l, int

r)32

intmain()

42return0;

43 }

st演算法

RMQ問題之ST演算法

st演算法 st演算法是用於解決rmq問題 區間最值問題 的一種強有力的工具。o nlogn 預處理,o 1 查詢最值,利用的是倍增的思想。但 但是,使用st演算法的條件是沒有修改操作,emmm 演算法流程 最大值為例 預處理 用f i j 表示,從i位置開始的2 j 個數中的最大值,例如f i j...

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

RMQ問題的ST演算法

st sparse table 演算法的基本思想是,預先計算從起點a i 開始長度為2的j次方 j 0,1.logn 的區間的最小值,然後在查詢時將任何乙個區間a i.j 劃分為兩個預處理好的可能重疊的區間,取這兩個重疊區間的最小值。在預處理階段,從起點a i 開始,任何乙個長度為2 j的區間都可以...