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