求区间最大值减去最小值的值,用线段树再好不过了,这里线段树的功能就是查询区间
的最大值和最小值,没有单点更新。
#include<cstdio> #include<algorithm> using namespace std; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 const int MAXN = 500107; int Max[MAXN << 2], Min[MAXN << 2]; int N, Q; void PushUp( int rt) { Max[rt] = max( Max[rt << 1], Max[rt << 1 | 1]); Min[rt] = min( Min[rt << 1], Min[rt << 1 | 1]); } void build( int l, int r, int rt) { int x, m = (l + r) >> 1; if( l == r) { scanf( "%d", &x); Max[rt] = x; Min[rt] = x; return; } build(lson); build(rson); PushUp(rt); } int queryMax(int L, int R, int l, int r, int rt) { int ret = 0, m = (l + r) >> 1; if( L <= l && r <= R) { return Max[rt]; } if( L <= m) ret = max( ret, queryMax( L, R, lson) ); if( R > m) ret = max( ret, queryMax(L, R, rson) ); return ret; } int queryMin(int L, int R, int l, int r, int rt) { int ret = 1 << 30, m = (l + r) >> 1; if( L <= l && r <= R) { return Min[rt]; } if( L <= m) ret = min( ret, queryMin(L, R, lson)); if( R > m) ret = min( ret , queryMin(L, R, rson)); return ret; } int main() { int L, R, s, t; while( scanf( "%d%d", &N, &Q) == 2) { build( 1, N, 1); while( Q --) { scanf( "%d%d", &L, &R); s = queryMin(L, R, 1, N, 1); t = queryMax(L, R, 1, N, 1); printf( "%d\n", t - s); } } return 0; }