RMQ的ST表演算法

2021-08-22 14:47:26 字數 1228 閱讀 2083

rmq(range minimum/maximum query),即區間最值查詢,是指這樣乙個問題:對於長度為n的數列a,回答若干次詢問rmq(i,j),返回數列a中下標在區間[i,j]中的最小/大值。

本文介紹一種比較高效的st演算法解決這個問題。st(sparse table)演算法可以在o(nlogn)時間內進行預處理,然後在o(1)時間內回答每個查詢。

1.預處理

設a[i]是要求區間最值的數列,f[i, j]表示從第i個數起連續2^j個數中的最大值。(dp的狀態)

例如: 

a數列為:3 2 4 5 6 8 1 2 9 7

f[1,0]表示第1個數起,長度為2^0=1的最大值,其實就是3這個數。

同理 f[1,1] = max(3,2) = 3, f[1,2]=max(3,2,4,5) = 5,f[1,3] = max(3,2,4,5,6,8,1,2) = 8;

並且我們可以容易的看出f[i,0]就等於a[i]。(dp的初始值)

我們把f[i,j]平均分成兩段(因為f[i,j]一定是偶數個數字),

從 i 到i + 2 ^ (j - 1) - 1為一段,i + 2 ^ (j - 1)到i + 2 ^ j - 1為一段(長度都為2 ^ (j - 1))。

於是我們得到了狀態轉移方程f[i, j]=max(f[i,j-1], f[i + 2^(j-1),j-1])。

2.查詢

假如我們需要查詢的區間為(i,j),那麼我們需要找到覆蓋這個閉區間(左邊界取i,右邊界取j)的最小冪(可以重複,比如查詢1,2,3,4,5,我們可以查詢1234和2345)。

兩個區間可以重複,因為兩個區間是否相交對區間最值沒有影響。(下圖引用自 fugtemypt的部落格)

因為這個區間的長度為j - i + 1,所以我們可以取k=log2( j - i + 1),則有:rmq(i, j)=max。

舉例說明,要求區間[1,5]的最大值,k = log2(5 - 1 + 1)= 2,即求max(f[1, 2],f[5 - 2 ^ 2 + 1, 2])=max(f[1, 2],f[2, 2]);

void st(int n) 

}}int rmq(int l, int r)

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 a i j i j n 返回數列a中下標在 i j 裡的最小 大 值,也就是說,rmq問題是指求區間最值的問題。關於rmq問題,還是有很多方法來求解的 像線段樹啊什麼的 這裡主...

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