题意:给出n个数,q次询问,每次询问一段区间输出区间内最大值和最小值的差。
解法:线段树。拿两个线段树分别维护最大值和最小值。
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 const int maxn = 50005; int Max[maxn << 2], Min[maxn << 2]; int a[maxn]; void pushUpMax(int rt) { Max[rt] = max(Max[rt << 1], Max[rt << 1 | 1]); } void buildMax(int l, int r, int rt) { if(l == r) { Max[rt] = a[l]; return ; } int m = (l + r) >> 1; buildMax(lson); buildMax(rson); pushUpMax(rt); } void pushUpMin(int rt) { Min[rt] = min(Min[rt << 1], Min[rt << 1 | 1]); } void buildMin(int l, int r, int rt) { if(l == r) { Min[rt] = a[l]; return ; } int m = (l + r) >> 1; buildMin(lson); buildMin(rson); pushUpMin(rt); } int queryMax(int ll, int rr, int l, int r, int rt) { if(ll <= l && rr >= r) return Max[rt]; int m = (l + r) >> 1; int res = INT_MIN; if(ll <= m) res = max(res, queryMax(ll, rr, lson)); if(rr > m) res = max(res, queryMax(ll, rr, rson)); return res; } int queryMin(int ll, int rr, int l, int r, int rt) { if(ll <= l && rr >= r) return Min[rt]; int m = (l + r) >> 1; int res = INT_MAX; if(ll <= m) res = min(res, queryMin(ll, rr, lson)); if(rr > m) res = min(res, queryMin(ll, rr, rson)); return res; } int main() { int n, q; while(~scanf("%d%d", &n, &q)) { for(int i = 1; i <= n; i++) scanf("%d", &a[i]); buildMax(1, n, 1); buildMin(1, n, 1); for(int i = 0; i < q; i++) { int maxx, minn; int l, r; scanf("%d%d", &l, &r); maxx = queryMax(l, r, 1, n, 1); minn = queryMin(l, r, 1, n, 1); printf("%d ", maxx - minn); } } return 0; }