RMQ原理及實現

2022-03-03 16:13:07 字數 792 閱讀 3076

rmq(range minimum/maximum query),區間最值查詢問題,是指:對於長度為n的數列a,回答若干次詢問rmq(i,j),返回數列a中下標在區間[i,j]中的最小/大值。

這裡介紹tarjan的sparse-table演算法,預處理時間為o(nlogn),但查詢只需要o(1),並且常數很小,演算法也很容易寫出。

1)預處理:

設a[i]是要求區間最值的數列,d[i, j]表示從第i個數起連續2^j個數中的最小值。(dp的狀態)

顯然d[i][0]的值就是a[i](dp初值),我們把d[i,j]平均分成兩段(因為d[i,j]一定是偶數個數字),從 i 到i + 2 ^ (j - 1) - 1為一段,i + 2 ^ (j - 1)到i + 2 ^ j - 1為一段(長度都為2 ^ (j - 1))。於是我們得到了狀態轉移方程d[i, j]=min(d[i,j-1], d[i + 2^(j-1),j-1]),**實現如下(這裡使用lrj藍書**):

1

void rmq_init(const vector &a)

2)查詢:

假如我們需要查詢的區間為(i,j),那麼我們需要找到覆蓋這個閉區間(左邊界取i,右邊界取j)的最小冪(可以重複,比如查詢1,2,3,4,5,5不是2的任意次方,但我們可以查詢1234和2345)。

這個查詢長度我們取範圍小於等於區間長度的最大(2^k),這樣我們查詢i到 i +(2^k)與j - (2^k) + 1到j的值,取二者最小值即可,**實現如下:

1

int rmq(int l, int

r)

RMQ(線段樹實現)

t t第乙個線段樹程式,還沒a過題,不過也很感動,先貼出來 下標從0開始,輸入 1 1 結束.求每一段區間之間的最大值。include include typedef struct treenodenode int mymax int a,int b node buildtree int a,int...

RMQ問題 ST table 實現

void rmq init int l,int r int st int l,int r rmq init 初始化,st查詢rmq range minimum maximum query 即區間最值查詢,是指這樣乙個問題 對於長度為n的數列a,回答若干詢問rmq a,i,j i,j n 返回數列a中...

RMQ 問題及 ST 表

rmq range minimum maximum query 問題指的是一類對於給定序列,要求支援查詢某區間內的最大 最小值的問題。很顯然,如果暴力預處理的話複雜度為 o n 2 而此類問題資料又往往很大,不僅會爆時間,陣列也存不下。我們需要一種能夠 o n log n 甚至 o n 預處理的資料...