题目大意:给出一个数列,求任意区间的区间最值之差。
分析:线段树模板题。
代码:
#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;
}