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,...