ST表(RMQ問題 區間最值查詢

2021-09-24 19:51:10 字數 778 閱讀 9229

3 2 4 5 6 8 1 2 9 7

預處理,用dp解決。

設a[i]是要求區間最值的數列,dp[i, j]表示從第i個數起連續2^j個數中的最大值。dp[1,0]表示第1個數起,長度為2^0=1的最大值,其實就是3這個數。 dp[1,2]=5,dp[1,3]=8,dp[2,0]=2,dp[2,1]=4……可以看出dp[i,0]其實就等於a[i],這樣就得到dp的初值。

狀態轉移方程。我們把dp[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這兩段。dp[i,j]就是這兩段的最值中的最值。於是得到動態規劃方程dp[i, j]=max(dp[i,j-1], dp[i + 2^(j-1),j-1])。

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

#includeusing namespace std;

typedef long long ll;

const int maxn=1e5+10;

int dp[maxn][30],a[maxn];

void rmq(int n)

int query(int l,int r)

int main()

}

RMQ問題(區間最值查詢)

有一類問題被稱作區間最值問題,描述的是,給定 n 個元素,需要查詢下標位於 p q 之間的最大 小值。首先確定,針對每一次查詢,肯定是不能動態求最值的,因為每次都要計算,可能造成比較多的時間耗費。有 一種比較好的解決辦法是,先得到所有結果,在查詢時直接取出結果。這樣,就需要一種資料結構,能夠覆蓋所有...

RMQ(模板 ST 區間最值,區間頻繁次數)

ps 介紹 rmq演算法,是乙個快速求區間最值的離線演算法,預處理時間複雜度o n log n 查詢o 1 所以是乙個很快速的演算法,當然這個問題用線段樹同樣能夠解決。1 求區間的最大值和最小值!如下 include include include include using namespace s...

RMQ(區間最值問題)

1 概述 lca least common ancestors 即最近公共祖先,是指這樣乙個問題 在有根樹中,找出某兩個結點u和v最近的公共祖先 另一種說法,離樹根最遠的公共祖先 rmq range minimum maximum query 即區間最值查詢,是指這樣乙個問題 對於長度為n的數列a,...