資料結構 RMQ問題

2022-05-16 10:44:58 字數 1816 閱讀 9055

rmq(range minimum/maximum query),即區間最值問題。

對於長度為n的數列a,回答若干查詢rmq(a,i,j)(i,j<=n),返回數列a中下標在i,j裡的最大(小)值。

假設當前題目要求區間最小值,我們令dp[i][j]代表從i開始,長度為\(2^\)這段區間的最小值。

於是便有:\(dp[i][j]=min(dp[i][j-1],dp[i+^][j-1])\)

分析可知,\(dp[i][j-1]\)代表從i開始,長度為\(2^\)區間一半中的最小值,而 \(dp[i+2^][j-1]\)即為區間的另一半。

即為區間的另一半。

最終(從下往上看):

\(dp[0][*]\)

\(dp[1][*]\)

\(dp[2][*]\)

\(dp[3][*]\)

\(dp[4][*]\)

\(dp[5][*]\)

\(dp[6][*]\)

\(dp[7][*]\)

\(dp[*\)][3]

\(1\)

\(dp[*\)][2]

\(1\)

\(1\)

\(1\)

\(5\)

\(2\)

\(dp[*][1]\)

\(3\)

\(1\)

\(1\)

\(5\)

\(7\)

\(6\)

\(2\)

\(dp[*][0]\)

\(4\)

\(3\)

\(1\)

\(5\)

\(7\)

\(8\)

\(6\)

\(2\)

預處理

根據狀態轉移方程,首先指定當區間長度為\(2^\)時的各初始值,隨後推出後面的結果。

void st_init(const vector&a)  \leq r-l+1\)的最大整數,則以l開頭、以r結尾的兩個長度為\(2^\)的區間合起來即覆蓋了查詢區間[l,r]

int rmq(int l, int r) {

int k=0;

while ((1<

return min(dp[l][k], dp[r-(1嗯!怎麼說呢?感覺線段樹在這種型別的題目中好像是最萬能的方法了。

對於一維中的線段樹,我們想要查詢某個區間的最值,首先就應該建樹咯~(具體方法省略

而在查詢時,我們可以從根節點向下遞迴搜尋,如下圖,假設查詢區間為[2,6]。

[2,6]這乙個大區間分解為不相交的三個小區間[2,3]、[4,5]、[6],而最終的結果便由這三個節點中所維護的資訊決定的!

我們假設查詢還是區間最小值,於是最終的結果為\(\min(1,7,6)=1\)

線段樹可以解決普通的[點/區間] 修改+查詢,當然它也可以解決樹中的路徑權值 修改+查詢(樹鏈剖分)。

資料結構專題小結 RMQ問題

範圍最小值問題 range minimum query 是指 給定乙個n個元素的陣列a 1 a 2 a n 設計乙個資料結構,支援查詢操作query l,r 計算min。該問題在實踐中常用tarjan的sparse table演算法。它的預處理時間是o n logn 但查詢只需要o 1 而且常數非常...

資料結構 線段樹實現ST表功能(RMQ問題)

以poj3264為例引入吧。其實還是很基礎的線段樹一種。這裡不用修改,只要建樹 查詢即可了。但是我一開始用c 的輸入輸出流配套io就tle了,換成c的scanf輸入就ac了,還是挺卡時間的吧。但處理區間rmq問題還是推薦st表,因為st表每次查詢就o 1 但線段樹的話,每次查詢的話就是乙個searc...

資料結構 二 RMQ 區間最值查詢

rmq 和普通陣列的區別是 rmq 是二維陣列,維度為 其中 rmq i j rmq i j rmq i j 表示的是從 a i a i a i 開始長度為 2 j2 j 2j的區間的最小值,那麼顯然,它的初始化可以遞迴進行,且複雜度為 o n logn o nlogn o nlog n 當要查詢 ...