rmq
(range minimum/maximum query)
,對於長度為n的數列a,回答若干詢問rmq(a,i,j)(i,j<=n),返回數列a中下標在i,j裡的最小(大)值。
主要方法:
樸素(即搜尋),複雜度為o(n)
線段樹能在對數時間內在陣列區間上進行更新與查詢。預處理 o(n), 查詢 o(logn)
定義線段樹在區間[i, j] 上如下:
第乙個節點維護著區間 [i, j] 的資訊。
if i
可知 n 個元素的線段樹的高度 為 [logn] + 1(只有根節點的樹高度為0) .
下面是區間 [0, 9] 的乙個線段樹:
線段樹和堆有一樣的結構, 因此如果乙個節點編號為 x ,那麼左孩子編號為2*x 右孩子編號為2*x+1.
使用線段樹解決rmq問題,關鍵維護乙個陣列m[num],num=2^(線段樹高度+1).
m[i]:維護著被分配給該節點(編號:i 線段樹根節點編號:1)的區間的最小值元素的下標。 該陣列初始狀態為-1.
#includeusing namespace std;
#define maxn 100
#define maxind 256 //線段樹節點個數
//構建線段樹,目的:得到m陣列.
void initialize(int node, int b, int e, int m, int a)
}//找出區間 [i, j] 上的最小值的索引
int query(int node, int b, int e, int m, int a, int i, int j)
int main()
; initialize(1, 0, sizeof(a)/sizeof(a[0])-1, m, a);
cout<
st演算法
(sparse table):它是一種動態規劃的方法。 預處理o(nlogn) 查詢o(1); (不能用來查詢動態區間)
以最小值為例。a為所尋找的陣列.
用乙個二維陣列f(i,j)記錄區間[i,i+2^j-1](持續2^j個)區間中的最小值。其中f[i,0] = a[i];
所以,對於任意的一組(i,j),f(i,j) = min來使用動態規劃計算出來。
這個演算法的高明之處不是在於這個動態規劃的建立,而是它的查詢:它的查詢效率是o(1).
假設我們要求a中區間[m,n]的最小值,找到乙個數k使得2^k
這樣,可以把這個區間分成兩個部分:[m,m+2^k-1]和[n-2^k+1,n].我們發現,這兩個區間是已經初始化好的.
前面的區間是f(m,k),後面的區間是f(n-2^k+1,k).
這樣,只要看這兩個區間的最小值,就可以知道整個區間的最小值!
以下為st演算法實現最小值查詢。
#include#includeusing namespace std;
#define mm 100010
#define maxn 500
#define maxm 500
int rmin[mm][20], rmax[mm][20];
int rminid[mm][20], rmaxid[mm][20];
inline int min(const int &a, const int &b)
inline int max(const int &a,const int &b)
void makermq(int len,int b) /*求最值*/
}inline int rmqminindex(int left,int right,int b)
inline int min(const int &a,const int &b)
void makermq_2d(const int rowlen,const int collen)
rmq;
void rmq::create()
int main()
{ int i,j,k = 0;
int t,a,b,c,d;
for (i = 1; i <= 300; ++i)
if (i < (1<
RMQ問題(區間最值查詢)
有一類問題被稱作區間最值問題,描述的是,給定 n 個元素,需要查詢下標位於 p q 之間的最大 小值。首先確定,針對每一次查詢,肯定是不能動態求最值的,因為每次都要計算,可能造成比較多的時間耗費。有 一種比較好的解決辦法是,先得到所有結果,在查詢時直接取出結果。這樣,就需要一種資料結構,能夠覆蓋所有...
RMQ 區間最值查詢 入門
講解不錯 一些細節講解 rmq range minimum maximum query 即區間最值查詢。rmq演算法一般用較長時間做預處理,時間複雜度為o nlogn 然後可以在o 1 的時間內處理每次查詢。主要是來解決 給你乙個陣列 其中有n個數字,現在給你多次詢問,給你區間 l,r 問你在這個區...
RMQ(區間最值查詢)入門知識
1.rmq range minimum maximum query 問題 是指 對於長度為n的數列a,回答若干詢問rmq a,i,j i,j n 返回數列a中下標在i,j裡的最小 大 值,也就是 說,rmq問題是指求區間最值的問題。2.主要方法及複雜度如下 1 樸素 即搜尋 o n o qn onl...