poj3264 RMQ問題的ST演算法

2021-07-24 22:30:57 字數 1682 閱讀 3967

rmq(range minimum/maximum query),即查詢給定區間的最值。

問題描述:對於給給定的陣列a[1…n],回答若干次查詢檔案rmq(i,j),即返回陣列a[i…j]的最大值/最小值

問題分析:該問題可以使用樸素查詢法,也可以用線段樹,st演算法,rmq與lca互相轉換。這裡我們分析高效的稀疏表演算法(sparse table, st演算法)。

st演算法是求解rmq問題的經典演算法,預處理時間為o(nl0gn),查詢時間為o(1)

預處理部分

預處理部分使用dp(動態規劃)解決。如果要求解的數列為a=,需要訪問最小值。

狀態空間的定義為:f[i,j]表示第i個數起,連續的2^j個數中的最大值.比如f[1,0]=min=2,f[2,2]=max = 1。顯然初始狀態為f[i,0]=a[i].

狀態轉移方程:因為f[i,j]中元素的個數為2^j個,因此我們考慮把其分為兩段。從ii+2^(j-1)-1和從i+2^(j-1)i+2^j-1。那麼狀態轉移方程為:f[i,j]=min(f[i,j-1], f[i+2^(j-1), j-1])

預處理的**如下:

void rmq(int n)

}}

查詢部分

查詢區間為[i,j],那麼我們只需要找到覆蓋這個閉區間的最小的冪即可(注意這裡第可以有重複的,比如查詢[3,4,5,6,7,8],需要查[3,4,5,6][5,6,7,8]).

區間長度為:j-i+1,那麼區間的最小冪為k=log2(j-i+1),則有rmq(a,i,j)=min(dp[i,k][j-2^k+1], k)

比如說,要求區間為[3,8],k=log2(8-3+1)=2。那麼rmq(a,3,8) = min(dp[3][2], dp[5][2])

題目大意:對於給定的陣列a,給定乙個區間範圍,返回這個區間最大值與最小值的差。

解題思路:rmq問題。

#include 

#include

#include

using

namespace

std;

#pragma warning(disable:4996)

const

int max_n = 50000 + 10;

const

int max_l = 20;//j的長度,大約可以訪問1000,000

int a[max_n];

int dp_min[max_n][max_l];

int dp_max[max_n][max_l];

void init(int n)

for (int j = 1; j < max_l; ++j)}}

}int rmq(int i, int j)

int main()

return

0;}

poj 3264 RMQ問題 ST演算法

部落格已遷至 www.lfy2us.com 比較裸的rmq問題,即對乙個無序陣列,查詢q次,每次查詢某個區間內最大值與最小值之差。解決此問題的演算法有三種 1 最簡單的方法就是o n 了 2 線段樹 3 st sparse table 演算法 其中st演算法為解此問題的最佳方法 預處理時間複雜度o ...

POJ 3264 RMQ問題 ST演算法

因為之前都是線段樹解決rmq問題,省腦子 因為寫的順手 但是因為rmq畢竟常數大,而且其實程式還相對st要長 以前寫過st演算法,但是因為每次都在糾結到底 1 呢,還是 1呢,邊界問題處理的我蛋都碎了好幾次,這次重新學習了一下st sparse table 演算法,好好的處理了這些問題的理解。st演...

poj3264 rmq演算法學習 ST表

解題關鍵 rmq模板題,可以用st表,亦可用線段樹等資料結構 log10和log2都可,這裡用到了對數的換底公式 類似於區間dp,用到了倍增的思想 f i j min f i j 1 f i 1 j 1 j 1 1 include2 include3 include4 include5 includ...