首先介紹一下什麼是rmq。rmq (range minimum/maximum query)問題是指求區間最值的問題,這個問題用線段樹同樣可以解決。
線段樹解決方法
st演算法是解決rmq問題較優的演算法,它是基於動態規劃和位運算實現的。它可以通過o(nl
ogn )的預處理對每次查詢在o(1)時間得出答案,是乙個很快速的演算法。
我們設dp[i][j]是區間[i,i+2j
-1]的最值,對於該區間它總共有2j
個數,所以dp[i][j]實際就是求i和i之後(包括i的)2j
個數的最值。
所以當我們要求解dp[i][j]時我們可以把它分為兩部分,每部分數的個數均為2j
−1,即分為區間[i,i+2j
−1-1]的最值(即dp[i][j-1])和區間[i+2j
−1,i+2j
-1]的最值(即dp[i+(1<<(j-1))][j-1])。
這樣我們就得出了狀態轉移方程
dp[i][j] = max/min(dp[i][j-1],dp[i+(1<<(j-1))][j-1])
當我們查詢任意區間[l,r]的最值的時候,先計算出該區間有多少個數(len=r-l+1),然後我們把它分為兩個區間(這兩個區間可以重疊但必須包含[l,r]中所有數),這樣我們直接取這兩個區間的最值即可。
現在關鍵問題就是怎麼分這兩個區間,其實就是計算2k
<=len,這樣我們就可以把它分成前2k
個數和後2k
個數,即區間[l,l+2k
-1](即dp[l][k])和區間[r-(1<<(k))+1,r](即dp[r-(1<<(k))+1][k])。
所以ans=max/min(dp[l][k],dp[r-(1<<(k))+1][k])
題意 給你n個數和q次詢問,(n<=50000,q<=200000),每次詢問區間[l,r]中最大值和最小值的差。
題解 就是裸題,直接維護最大值和最小值即可。
**
//#include
#include
#include
#include
#include
#include
using
namespace
std;
typedef
long
long ll;
const
int maxn = 5e5+5;
int ma[maxn][20],mi[maxn][20];
int n,m;
void st(int len)
}}int rmq(int l,int r)
int main()
return
0;}
rmp演算法詳細介紹 poj3264
rmq range minimum maximum query 問題 rmq問題是給定乙個區間,求這個區間中的最大或最小值的問題 rmq採用動態規劃的思想來求解 st演算法 square table 預處理 預處理使用 dp的思想,f i,j 表示 i,i 2 j 1 區間中的最小值。例如,f 0,...
對於POJ3264的思考
嗯嗯poj3264就是你啦 題目大意 給定區間多次求區間最大值最小值之差 線段樹維護 開始寫了,但願能跑個好名次嘿嘿嘿 北大郭老 郭煒 的歷程用堆式線段樹,那好吧,那我也寫堆式的正好不用指標了 不過他的歷程足足跑了3秒我覺的不太靠譜阿你說呢 結果 我只比他少了200ms還是資料讀入優勢 includ...
RMQ問題ST演算法 POJ 3264
st演算法o nlogn 預處理,o 1 的查詢指定區間的最值 以最小值為例 基本上是把待求區間 l,r 分為兩段長為len的區間 左邊一段為 l,l len 1 右邊一段為 r len 1,r len必須使得兩段區間覆蓋待求區間 設所求陣列為w 那麼,所求最小值就是兩個區間的最小值間的最小值 即m...