RMQ問題 st 線段樹

2021-07-09 03:08:52 字數 2398 閱讀 8976

j#演算法

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

主要方法及複雜度(處理複雜度和查詢複雜度)如下: 

1.樸素(即搜尋) o(n)-o(n) 

2.線段樹(segment tree) o(n)-o(qlogn) 

3.st(實質是動態規劃) o(nlogn)-o(1) 

線段樹方法

線段樹能在對數時間內在陣列區間上進行更新與查詢。 

定義線段樹在區間[i, j] 上如下: 

第乙個節點維護著區間 [i, j] 的資訊。 

if icpp**  

#include

using

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):它是一種動態規劃的方法。 

以最小值為例。a為所尋找的陣列. 

用乙個二維陣列f(i,j)記錄區間[i,i+2^j-1](持續2^j個)區間中的最小值。其中f[i,0] = a[i]; 

所以,對於任意的一組(i,j),f(i,j) = min來使用動態規劃計算出來。 

這個演算法的高明之處不是在於這個動態規劃的建立,而是它的查詢:它的查詢效率是o(1). 

假設我們要求區間[m,n]中a的最小值,找到乙個數k使得2^kcpp**  

#include

#include

#include

using

namespace std;  

#define m 100010

#define maxn 500

#define maxm 500

int dp[m][18];  

/**一維rmq st演算法

*構造rmq陣列 makermq(int n,int b) o(nlog(n))的演算法複雜度

*dp[i][j] 表示從i到i+2^j -1中最小的乙個值(從i開始持續2^j個數)

*dp[i][j]=min

*查詢rmq rmq(int s,int v)

*將s-v 分成兩個2^k的區間

*即 k=(int)log2(s-v+1)

*查詢結果應該為 min(dp[s][k],dp[v-2^k+1][k])

*/void makermq(int n,int b)  

int rmq(int s,int v)  

void makermqindex(int n,int b) //返回最小值對應的下標

int rmqindex(int s,int v,int b)  

int main()  

;  //返回下標

makermqindex(sizeof(a)/sizeof(a[0]),a);  

cout

makermq(sizeof(a)/sizeof(a[0]),a);  

cout

}  

應用:cpp**  

#include

#include

#include

using

namespace std;  

#define maxn 50001

int a[maxn];  

int dpmax[maxn][40];  

int dpmin[maxn][40];  

int getmin(int a,int b)  

int getmax(int a,int b)  

void make_big_rmq(int n)  

}  void make_min_rmq(int n)  

}  int get_big_rmq(int a,int b)  

int get_min_rmq(int a,int b)  

int main()  

}  return 0;  

}  

RMQ問題 線段樹演算法,ST演算法優化

對於長度為n的數列a,回答若干詢問rmq a,i,j i,j n 返回數列a中下標在 i,j 裡的最小 大 值,也就是說,rmq問題是指求區間最值的問題 主要方法及複雜度 處理複雜度和查詢複雜度 如下 1.樸素 即搜尋 o n o n 2.線段樹 segment tree o n o qlogn 3...

RMQ問題 線段樹演算法,ST演算法優化

對於長度為n的數列a,回答若干詢問rmq a,i,j i,j n 返回數列a中下標在 i,j 裡的最小 大 值,也就是說,rmq問題是指求區間最值的問題 主要方法及複雜度 處理複雜度和查詢複雜度 如下 1.樸素 即搜尋 o n o n 2.線段樹 segment tree o n o qlogn 3...

資料結構 線段樹實現ST表功能(RMQ問題)

以poj3264為例引入吧。其實還是很基礎的線段樹一種。這裡不用修改,只要建樹 查詢即可了。但是我一開始用c 的輸入輸出流配套io就tle了,換成c的scanf輸入就ac了,還是挺卡時間的吧。但處理區間rmq問題還是推薦st表,因為st表每次查詢就o 1 但線段樹的話,每次查詢的話就是乙個searc...