题目是经典 查询区间最值问题
可以用RMQ线段树,或者st表
rmq线段树 建树 查询都是logn 支持更新元素
st表建树logn 查询o(1)! 不支持更新元素
以下是st表代码
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <map> #include <set> #include <vector> using namespace std; const int maxn=50005; int h[maxn]; int mx[maxn][16],mn[maxn][16]; int n,q; int max(int a,int b) { if (a<b) return b; return a; } int min(int a,int b) { if (a>b) return b; return a; } void rmq_init() { int i,j; for(j=1;j<=n;j++) mx[j][0]=mn[j][0]=h[j]; int m=floor(log((double)n)/log(2.0)); for(i=1;i<=m;i++){ for(j=n;j>0;j--){ mx[j][i]=mx[j][i-1]; if(j+(1<<(i-1))<=n) mx[j][i]=max(mx[j][i],mx[j+(1<<(i-1))][i-1]); } } for(i=1;i<=m;i++){ for(j=n;j>0;j--){ mn[j][i]=mn[j][i-1]; if(j+(1<<(i-1))<=n) mn[j][i]=min(mn[j][i],mn[j+(1<<(i-1))][i-1]); } } } int rmq_max(int l,int r) { int m=floor(log((double)(r-l+1))/log(2.0)); int a=max(mx[l][m],mx[r-(1<<m)+1][m]); return a; //a为最大值,b为最小值 } int rmq_min(int l,int r) { int m=floor(log((double)(r-l+1))/log(2.0)); int b=min(mn[l][m],mn[r-(1<<m)+1][m]); return b; //a为最大值,b为最小值 } int main() { int i,a,b; cin>>n>>q; for (i=1;i<=n;i++) cin>>h[i]; rmq_init(); for (i=1;i<=q;i++) { scanf("%d%d",&a,&b); printf("%d\n",rmq_max(a,b)-rmq_min(a,b )); } return 0; }
以下是线段树代码:
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <cstdio> #include <algorithm> #include <iostream> #include <queue> #include <set> #include <vector> #define inf 0x7fffffff #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const int maxn = 50005; int st_min[maxn<<2],st_max[maxn<<2]; int aa[maxn]; inline int minn(int a,int b) { return a>b?b:a; } inline int maxx(int a,int b) { return a>b?a:b; } void PushUP(int rt) { st_min[rt] = minn(st_min[rt<<1],st_min[rt<<1|1]); st_max[rt] = maxx(st_max[rt<<1],st_max[rt<<1|1]); } int ok=0; void build(int l,int r,int rt) { if (l == r) { st_min[rt]=aa[++ok]; st_max[rt] = st_min[rt]; return ; } int m = (l + r) >> 1; build(lson); build(rson); PushUP(rt); } int query_min(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { return st_min[rt]; } int m = (l + r) >> 1; int ret1 = inf,ret2 = inf; if (L <= m) ret1 = query_min(L , R , lson); if (R > m) ret2 = query_min(L , R , rson); return minn(ret1,ret2); } int query_max(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { return st_max[rt]; } int m = (l + r) >> 1; int ret1 = -inf,ret2 = -inf; if (L <= m) ret1 = query_max(L , R , lson); if (R > m) ret2 = query_max(L , R , rson); return maxx(ret1,ret2); } int main(void) { int n,m,i,a,b; while(scanf("%d%d",&n,&m)!=EOF) { for (i=1;i<=n;i++) scanf("%d",&aa[i]); build(1 , n , 1); for(i=1;i<=m;i++) { scanf("%d %d",&a,&b); printf("%d\n",query_max(a,b,1,n,1)-query_min(a,b,1,n,1) ); } } return 0; }