求区间最大最小值的差值。
用树状数模拟组线段树建树,数组的每个节点保存:区间的左右两点 和 该区间的最大最小值。
注意区间查询的临界值的判断。
#include<stdio.h>
#define maxn 200010
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1000010
int c_min, c_max;
int n, q;
struct node{
int minh, maxh;
int lc, rc;
}sum[maxn<<2];
int max(int a, int b){
return a>b?a:b;
}
int min(int a, int b){
return a<b?a:b;
}
void PushUp(int rt){
sum[rt].minh = min(sum[rt<<1].minh, sum[rt<<1|1].minh);
sum[rt].maxh = max(sum[rt<<1].maxh, sum[rt<<1|1].maxh);
}
void build(int l, int r, int rt){
sum[rt].lc = l;
sum[rt].rc = r;
if(l == r){
scanf("%d", &sum[rt].minh);
sum[rt].maxh = sum[rt].minh;
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void Query(int L, int R, int l, int r, int rt){
if(L==sum[rt].lc && R==sum[rt].rc){
if(sum[rt].minh < c_min) c_min = sum[rt].minh;
if(sum[rt].maxh > c_max) c_max = sum[rt].maxh;
return ;
}
int m = (l+r)>>1;
if(L <= m){
if(R>m) Query(L, m, lson);
else Query(L, R, lson);
}
if(R > m){
if(L<m+1) Query(m+1, R, rson);
else Query(L, R, rson);
}
}
int main(){
freopen("in.txt", "r", stdin);
int a, b;
while(scanf("%d %d", &n, &q) != EOF){
build(1, n, 1);
while(q--){
c_min = inf, c_max = 0;
scanf("%d %d", &a, &b);
Query(a, b, 1, n, 1);
printf("%d\n", c_max - c_min);
}
}
return 0;
}