區間最大 小值 RMQ演算法

2021-07-29 06:38:29 字數 897 閱讀 8653

rmq(range minimum/maximum query),即區間最值查詢,是指這樣乙個問題:對於長度為n的數列a,回答若干詢問rmq(a,i,j)(i,j<=n),返回數列a中下標在i,j之間的最小/大值。這兩個問題是在實際應用中經常遇到的問題,本文介紹了當前解決這兩種問題的比較高效的演算法。

首先是預處理,用動態規劃(dp)解決。設a[i]是要求區間最值的數列,f[i, j]表示從第i個數起連續2^j個數中的最大值。例如數列3 2 4 5 6 8 1 2 9 7,f[1,0]表示第1個數起,長度為2^0=1的最大值,其實就是3這個數。 f[1,2]=5,f[1,3]=8,f[2,0]=2,f[2,1]=4……從這裡可以看出f[i,0]其實就等於a[i]。這樣,dp的狀態、初值都已經有了,剩下的就是狀態轉移方程。我們把f[i,j]平均分成兩段(因為f[i,j]一定是偶數個數字),從i到i+2^(j-1)-1為一段,i+2^(j-1)到i+2^j-1為一段(長度都為2^(j-1))。用上例說明,當i=1,j=3時就是3,2,4,5 和 6,8,1,2這兩段。f[i,j]就是這兩段的最大值中的最大值。於是我們得到了動態規劃方程f[i, j]=max(f[i,j-1], f[i + 2^(j-1),j-1])。

然後是查詢。取k=[log2(j-i+1)],則有:rmq(a, i, j)=min。 舉例說明,要求區間[2,8]的最大值,就要把它分成[2,5]和[5,8]兩個區間,因為這兩個區間的最大值我們可以直接由f[2,2]和f[5,2]得到。

void rmq(int num) //預處理->o(nlogn)

}

當然,該問題也可以用線段樹(也叫區間樹)解決,演算法複雜度為:o(n)~o(logn)。

RMQ 區間最值查詢演算法

rmq range minimum maximum query 對於長度為n的數列a,回答若干詢問rmq a,i,j i,j n 返回數列a中下標在i,j裡的最小 大 值。主要方法 樸素 即搜尋 複雜度為o n 線段樹能在對數時間內在陣列區間上進行更新與查詢。預處理 o n 查詢 o logn 定義...

數列區間最大值 RMQ問題(ST演算法模板)

輸入一串數字,給你 m個詢問,每次詢問就給你兩個數字 x,y,要求你說出 x 到 y 這段區間內的最大數。輸入格式 第一行兩個整數 n,m 表示數字的個數和要詢問的次數 接下來一行為 n 個數 接下來 m 行,每行都有兩個整數x,y 輸出格式 輸出共 m 行,每行輸出乙個數。樣例樣例輸入 10 2 ...

RMQ求區間最大頻率

暫時只做了遞增序列的求解方法,就是將原數列處理成個數的陣列,類似於字首和的東西,對這個頻率陣列求區間最大值,但是僅僅維護區間max還是不夠的,好比這種情況 原數列 1 1 1 2 3 5 5 7 7 頻率陣列 1 2 3 1 1 1 2 1 2 下標 1 2 3 4 5 6 7 8 9 如果查詢區間...