RMQ演算法學習筆記

2021-10-24 12:12:38 字數 2363 閱讀 6062

以我個人的看法,與其說rmq是演算法,還不如說是一類問題,即區間(range)最大/小值(minimum/maximum)查詢(query)

有三種辦法可以解決這類問題

第一種是暴力查詢

for

(int i=n1,i<=n2;i++

)

如果查詢次數是0第三種st方法,可以在o(nlogn)的預處理之後做到o(1)的查詢速度

原理大概是二分吧

分成兩部分:預處理和查詢

難點是迴圈的控制(賊難受,思考了很長時間才稍微理解)

先說預處理:

以最大值為例:

假設有陣列arr,陣列長度len

那麼我們需要來乙個二維陣列dp[i][j];

i 是1<=i<=len的規模

j 是log2(len)的規模

為啥?因為dp[i][j]的含義是從下標為i的字元開始,往後2j個字元的最大值

也就是dp[i][j] = for(arr[i]到arr[i+2j-1])的最大值

那麼dp[i][0] 就是從arr[i]開始20=1個字元的最大值,這裡需要說一下,我們不用0下標,也就是說dp[i][0]就是arr[i]

o(nlogn)

通過乙個雙重迴圈

for

(int j=1;

(1<< j )

<=len;j++

)//很奇怪是吧?為什麼和以往把i放在外面的思路不一樣呢?

for(

int i=

1;i +(1

<< j)-1

<=len;i++

) dp[i]

[j]=

max(dp[i]

[j-1

],dp[i +(1

<< j-1)

][j-1]

);

把陣列原模原樣的弄到dp中是這個樣子的

之後我們把j放在外面,把i放在裡面做迴圈,為的是讓陣列一列一列的dp而不是一行一行的dp,如果把i放在外面,情況就是這樣的:

dp[1][1] = max(dp[1][0],dp[1+1][0]);沒問題,等於1

dp[1][2] = max(dp[1][1],dp[1+2][1]);dp[1][1]是有了,但是dp[3][1]不是還沒加工嗎?

dp思想:也就是說,每段dp元素的值是之前已經處理過的兩個元素之間的關係得出來的

然後我們先抽象的理解下這段原理

dp[i][k],也就是說把從i開始到i+2k-1個元素的最值找到並存到dp[i][k]中去,

那麼我們可以吧這段分兩份一起找

乙份是從 i 到i +2k-1-1

這不就是dp[i][k-1]嗎

乙份是從i + 2k-1到 i + 2k-1

兩份長度都是2k-1

長度一樣, j 值一樣, i 加上 2k-1

就是dp[i+(1 << j-1)][j-1]的來歷

正好湊出2k個元素

舉例 dp[2][3] = max(dp[2][2] , dp[2+22][2])

黃色代表dp[2][2]的整體,綠色代表dp[2 + 22][2]的整體,dp[2][3]最後成綠色代表綠色找出來的值更大

int

find

(int n1,

int n2)

k的作用是把區間的長度對2取對數的向下取整

找到區間n1的 j 標

這樣就不把從n1開始到下標n1+2n-1的值全都檢索一遍了嗎

那麼問題來了:

既然是向下取整,2k一定是小於等於n2-n1+1的,缺少的一部分怎麼辦?

我們可以直接從n2往前找

不會把,不是說 j 標是往後2j個嗎?

對,所以我們直接找n2前面2k的值就可以了

也就是**dp[n2-(1<

來張感受一下

poj3264

uva 11235(我進不去uva**。。。不會翻牆)

演算法討論 RMQ 學習筆記

模板及講解 運用st表實現區間詢問區間最大 最小,初始化時間複雜度o nlog n 查詢o 1 模板題 poj 3264 include include include include define ms i,j memset i,j,sizeof i using namespace std con...

RMQ(範圍最值問題)演算法學習

rmq演算法適合求解對乙個陣列多次查詢給定範圍內的最值。預處理操作 令d i,j 表示從i開始,長度為2 j的一段元素的最值,可以用遞推公式寫出d i,j min 原理如圖所示 複雜度 因為2 j n,所以d陣列的元素不會超過nlogn個,計算每個d需要o 1 所以總的時間複雜度是o nlogn 查...

演算法 學習筆記

1.輸入輸出演算法至少有乙個或多個輸出 2.有窮性 3.確定性 4.可行性 1.正確性a.演算法程式沒有語法錯誤 b.演算法程式對於合法的輸入資料能夠產生滿足要求的輸出結果 c.演算法程式對於非法的輸入資料能夠得出滿足規格說明的結果 d.演算法對於精心選擇的,甚至刁難的測試資料都有滿足要求的輸出結果...