RMQ 區間最值查詢演算法

2021-06-09 04:47:06 字數 2098 閱讀 7951

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...