ST(稀疏表)演算法

2021-08-07 02:16:28 字數 2255 閱讀 1464

作用:st演算法是用來求解給定區間rmq的最值,本文以最小值為例

舉例:給出一陣列a[0~5] = ,則區間[2,5]之間的最值為1。

(1)離線預處理:運用dp思想,用於求解區間最值,並儲存到乙個二維陣列中。

具體解釋:

(1)離線預處理:

st演算法使用dp思想求解區間最值,貌似屬於區間動態規劃,不過區間在增加時,每次並不是增加乙個長度,而是使用倍增的思想,每次增加2^i個長度。

使用f[i,j]表示以i為起點,區間長度為2^j的區間最值,此時區間為[i,i + 2^j - 1]。

比如,f[0,2]表示區間[0,3]的最小值,即等於4,f[2,2]表示區間[2,5]的最小值,即等於1。

在求解f[i,j]時,st演算法是先對長度為2^j的區間[i,i + 2^j - 1]分成兩等份,每份長度均為2^(j - 1)。之後在分別求解這兩個區間的最值f[i,j - 1]和f[i + 2^(j - 1),j - 1]。,最後在結合這兩個區間的最值,求出整個區間的最值。特殊情況,當j = 0時,區間長度等於0,即區間中只有乙個元素,此時f[i,0]應等於每乙個元素的值。

舉例:要求解f[1,2]的值,即求解區間[1,4] = 的最小值,此時需要把這個區間分成兩個等長的區間,即為[1,2]和[3,4],之後分別求解這兩個區間的最小值。此時這兩個區間最小值分別對應著f[1,1] 和 f[3,1]的值。

狀態轉移方程是 f[i,j] = min(f[i,j - 1],f[i + 2^(j - 1),j - 1])

初始狀態為:f[i,0] = a[i]。

在根據狀態轉移方程遞推時,是對每一元素,先求區間長度為1的區間最值,之後再求區間長度為2的區間最值,之後再求區間長度為4的區間最值....,最後,對每乙個元素,在求解區間長度為log2^n的區間最值後,演算法結束,其中n表示元素個數。

即:先求f[0][1],f[1][1],f[2][1],f[3][1],,,f[n][1],再求.f[0][2],f[1][2],f[2][2],f[3][2],,,f[m][2],... 。

在預處理期間,每乙個狀態對應的區間長度都為2^i。由於給出的待查詢區間長度不一定恰好為2^i,因此我們應對待查詢的區間進行處理。

這裡我們把待查詢的區間分成兩個小區間,這兩個小區間滿足兩個條件:(1)這兩個小區間要能覆蓋整個區間(2)為了利用預處理的結果,要求小區間長度相等且都為2^i。注意兩個小區間可能重疊。

如:待查詢的區間為[3,11],先盡量等分兩個區間,則先設定為[3,7]和[8,11]。之後再擴大這兩個區間,讓其長度都等於為2^i。剛劃分的兩個區間長度分別為5和4,之後繼續增加區間長度,直到其成為2^i。此時滿足兩個條件的最小區間長度為8,此時i = 3。

在程式計算求解區間長度時,並沒有那麼麻煩,我們可以直接得到i,即等於直接對區間長度取以2為底的對數。這裡,對於區間[3,11],其分解的區間長度為int(log(11 - 3 + 1)) = 3,這裡log是以2為底的。

根據上述思想,可以把待查詢區間[x,y]分成兩個小區間[x,x + 2^i - 1] 和 [y - 2^i + 1,y] ,其又分別對應著f[x,i]和f[y - 2^i + 1,i],此時為了求解整個區間的最小值,我們只需求這兩個值得最小值即可,此時複雜度是o(1)。

#include #include using namespace std;

/*方程

f[i,j]:區間[i,i + 2^j - 1]的最小值,此時區間長度為2^j

f[i,j] = min(f[i,j - 1],f[i + 2^(j - 1),j - 1])

f[i,0] = narr[i];*/

int f[1000000][20];//待比較元素的個數最大為1百萬

void sparsetable(int narr,int nlen)

//遞推

int nlog = int(log(double(nlen))/log(2.0));

for (int j = 1;j <= nlog;j++)

} }

}

int rmq(int narr,int nlen,int nstart,int nend)

int main()

; sparsetable(narr,6);

cout<

ST演算法(Sparse Table,稀疏表)介紹

st演算法簡介 資訊學競賽中,經常會出現rmq問題,即求區間最大 小 值問題。那麼,我們該如何求解呢?st演算法橫空出世。st演算法 sparse table,稀疏表 主要用於解決區間最值問題 即 rmq問題 因為st演算法求解rmq問題時的時間複雜度只有o nlogn 查詢時間複雜度為常數階o 1...

演算法 ST表

想學習一下lca倍增,先 水乙個黃題 學一下st表 這是乙個運用倍增思想,通過動態規劃來計算區間最值的演算法 求出區間最值 回答詢問 求出區間最值 用 f i j 來儲存從第 j 個點開始,向後 2 i 1 個點 共 2 i 個點 中的最值 包括本身 利用二分法的思想,將區間 j,j 2 i 1 平...

st 表演算法模板

借鑑於 st表是基於二分的思想,st i j 表示j到j 2 n 1區間內的最值,長度為2 n 構建的時候用二分構建,那麼st i j 如何用其他狀態來繼承呢?j到j 2 i 1的長度為2 i,那麼一半的長度就等於2 i 1 那麼前半段的狀態表示為st i 1 j 後半段的長度也為2 i 1 起始位...