rmq演算法詳解 模板

2021-08-06 04:34:47 字數 3102 閱讀 2909

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

}  

#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

#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

}  

#include#include#includeusing 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 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;  

}  

#include#include#includeusing namespace std;

#define maxn 50001

int a[maxn];

int dpmax[maxn][40];

int dpmin[maxn][40];

int getmin(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演算法詳解

下面我們從乙個實際問題來解釋rmq 我們假設陣列arr為 1,3,6,7,4,2,5 我們設二維陣列dp i j 表示從第i位開始連續2 j個數中的最小值。例如dp 2 1 就表示從第二位數開始連續兩個數的最小值 也就是從第二位數到第三位數的最小值 即3,6中的最小值,所以dp 2 1 3 其實我們...

RMQ之ST演算法模板

1 include2 include 3 include4 using namespace std 5const int n 1e6 111 6 int max n 21 min n 21 a n 7void st int a,int n 預處理,o nlogn 820 21 22 23int lo...

演算法競賽模板 RMQ(計算區間最值)

一維rmq 1 dp i,j 表示從第i個數起連續2j個數中的 最大值min 最小值max 最大公約數gcd 通過更改下列 中的紅色函式即可實現。2 b陣列放置所需查詢的數列。const int max 305 int dp max 20 int mm max void initrmq int n,...