题目大意:给出一个数列,求任意区间的区间最值之差。
分析:线段树模板题。
代码:
#include <cstdio> #include <algorithm> using namespace std; #define INF 0xffffff0 const int maxn = 50010; struct Node { int l, r; int mi, mx; int Mid(){ return (l+r)/2; } }; Node tree[3*maxn]; int ans, minv, maxv; void Build(int root, int l, int r) { tree[root].l = l; tree[root].r = r; tree[root].mi = INF; tree[root].mx = -INF; if(l != r) { Build(2*root+1, l, (l+r)/2); Build(2*root+2, (l+r)/2+1, r); } } void Insert(int root, int i, int x) { if(tree[root].l == tree[root].r) { tree[root].mi = tree[root].mx = x; return; } tree[root].mi = min(tree[root].mi, x); tree[root].mx = max(tree[root].mx, x); if(i <= tree[root].Mid()) Insert(2*root+1, i, x); else Insert(2*root+2, i, x); } void Query(int root, int l, int r) { if(minv <= tree[root].mi && maxv >= tree[root].mx) return; if(l == tree[root].l && r == tree[root].r) { minv = min(minv, tree[root].mi); maxv = max(maxv, tree[root].mx); return; } if(r <= tree[root].Mid()) Query(2*root+1, l, r); else if(l > tree[root].Mid()) Query(2*root+2, l, r); else { Query(2*root+1, l, tree[root].Mid()); Query(2*root+2, tree[root].Mid()+1, r); } } int main() { int n, q; scanf("%d%d", &n, &q); Build(0, 1, n); int x; for(int i = 1; i <= n; i++) { scanf("%d", &x); Insert(0, i, x); } while(q--) { int L, R; scanf("%d%d", &L, &R); minv = INF; maxv = -INF; Query(0, L, R); printf("%d\n", maxv-minv); } return 0; }