瘋子的演算法總結14 ST演算法(區間最值)

2022-09-15 06:27:10 字數 1335 閱讀 8640

借助倍增和動態規劃可以實現o(1)的時間複雜度的查詢

預處理:

①區間dp   轉移方程  f[i][j] = min(max同理)(f[i][j - 1],f[i + ][j - 1])  f[i][j]表示從i位置開始的後2^j個數中的最大值

用f[i][j]表示從j到j+2^i-1的最小值(長度顯然為2^i)。

任意一段的最小值顯然等於min(前半段最小值,後半段最小值)。

那麼f[i][j]如何用其他狀態來繼承呢?

j到j+2^i-1的長度為2^i,那麼一半的長度就等於2^(i-1)。

那麼前半段的狀態表示為f[i-1][j]。

後半段的長度也為2^(i-1),起始位置為j+2^(i-1)。

那麼後半段的狀態表示為f[i-1][j+2^(i-1)]。

②不過區間在增加時,每次並不是增加乙個長度,而是基於倍增思想,用二進位制右移,每次增加2^i個長度 ,最多增加logn次

這樣預處理了所有2的冪次的小區間的最值

關於倍增法鏈結

查詢:

③對於每個區間,分成兩段長度為的區間,再取個最值(這裡的兩個區間是可以有交集的,因為重複區間並不影響最值)

比如3,4,6,5,3一種分成3,4,6和6,5,3,另一種分成3,4,6和5,3,最大值都是6,沒影響。

首先明確 2^log(a)>a/2

這個很簡單,因為log(a)表示小於等於a的2的最大幾次方。比如說log(4)=2,log(5)=2,log(6)=2,log(7)=2,log(8)=3,log(9)=3…….

那麼我們要查詢x到y的最小值。設len=y-x+1,t=log(len),根據上面的定理:2^t>len/2,從位置上來說,x+2^t越過了x到y的中間!

因為位置過了一半,所以x到y的最小值可以表示為min(從x往後2^t的最小值,從y往前2^t的最小值),前面的狀態表示為f[t][x]

設後面(從y往前2^t的最小值)的初始位置是k,那麼k+2^t-1=y,所以k=y-2^t+1,所以後面的狀態表示為f[t][y-2^t+1]

所以x到y的最小值表示為f(f[t][x],f[t][y-2^t+1]),所以查詢時間複雜度是o(1)

④所以o(nlogn)預處理,o(1)查詢最值  但不支援修改

預處理時間複雜度o(nlogn),查詢時間o(1)。

#include#include#include#includeusing namespace std;

int map[1000005][20];

int n,k;

void work()

{ int i,j;

for(j=1;1<

瘋子的演算法總結14 ST演算法(區間最值)

借助倍增和動態規劃可以實現o 1 的時間複雜度的查詢 預處理 區間dp 轉移方程 f i j min max同理 f i j 1 f i j 1 f i j 表示從i位置開始的後2 j個數中的最大值 用f i j 表示從j到j 2 i 1的最小值 長度顯然為2 i 任意一段的最小值顯然等於min 前...

st演算法模板(區間最值)

f 1,0 表示第1個數起,長度為2 0 1的最大值,其實就是3這個數。f 1,2 5,f 1,3 8,f 2,0 2,f 2,1 4 從這裡可以看出f i,0 其實就等於a i 這樣,dp的狀態 初值都已經有了,剩下的就是狀態轉移方程。我們把f i,j j 1 平均分成兩段 因為j 1時,f i,...

求解區間最值的ST演算法

作用 st演算法是用來求解給定區間rmq的最值,本文以最小值為例 舉例 給出一陣列a 0 5 則區間 2,5 之間的最值為1。1 離線預處理 運用dp思想,用於求解區間最值,並儲存到乙個二維陣列中。具體解釋 1 離線預處理 st演算法使用dp思想求解區間最值,貌似屬於區間動態規劃,不過區間在增加時,...