求区间的最大值,最小值的差值。
RMQ问题
1、Sparse-Table算法,预处理时间O(nlogn),查询时间O(1)
2、线段树(略)
RMQ模板
struct RMQ{ int d[maxn][maxlog]; void init(int a[], int n) { for(int i=0; i<n; ++i) d[i][0] = a[i]; for(int j=1; (1<<j) <= n; ++j) for(int i=0; i + (1<<j)-1 <n; ++i) d[i][j] = max(d[i][j-1], d[i+(1<<(j-1))][j-1]); } int query(int L, int R){ int k = 0; while((1<<(k+1)) <= R-L+1) k++; return max(d[L][k], d[R-(1<<k)+1][k]); } };
ST算法
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 50005; int ST_min[maxn][30], ST_max[maxn][30]; int preLog2[maxn], a[maxn]; void st_prepare(int n) { preLog2[1] = 0; for(int i = 2; i <= n; ++i) { preLog2[i] = preLog2[i-1]; if ((1 << preLog2[i] + 1) == i) { ++preLog2[i]; } } for(int i=n-1; i >= 0; --i) { ST_min[i][0] = ST_max[i][0] = a[i]; for(int j = 1; (i + (1 << j) - 1) < n; ++j) { ST_min[i][j] = min(ST_min[i][j-1], ST_min[i + (1<<j-1)][j-1]); ST_max[i][j] = max(ST_max[i][j-1], ST_max[i + (1<<j-1)][j-1]); } } } int query(int l, int r) { int len = r - l + 1, k = preLog2[len]; int Max = max(ST_max[l][k], ST_max[r-(1<<k)+1][k]); int Min = min(ST_min[l][k], ST_min[r-(1<<k)+1][k]); return Max - Min; } int main() { int n, m, i, l, r; int num[maxn]; scanf("%d%d",&n,&m); for(i=0; i<n; ++i) scanf("%d",&a[i]); st_prepare(n); while(m--) { scanf("%d%d", &l, &r); l--, r--; printf("%d\n", query(l, r)); } return 0; }