线段树。
#include <cstdio>
#include <cstring>
#define isInside(L, R, u, v) (u <= L && R <= v)
#define isOutside(L, R, u, v) (R < u || v < L)
const int MAXN = 2e5 + 100;
typedef long long ll;
typedef struct Seg{
ll p[MAXN], seg[MAXN * 4], lazy[MAXN * 4], min[MAXN * 4], max[MAXN * 4];
ll Min(ll x, ll y){
return x <= y ? x : y;
}
ll Max(ll x, ll y){
return x >= y ? x : y;
}
void clear(){
memset(lazy, 0, sizeof(lazy));
memset(seg, 0, sizeof(seg));
memset(min, 0, sizeof(min));
memset(max, 0, sizeof(max));
}
void push_up(int pos){
seg[pos] = seg[pos << 1] + seg[pos << 1 | 1];
min[pos] = Min(min[pos << 1], min[pos << 1 | 1]);
max[pos] = Max(max[pos << 1], max[pos << 1 | 1]);
}
void push_down(int pos, int L, int R){
if(lazy[pos]){
seg[pos] += lazy[pos] * (R - L + 1);
min[pos] += lazy[pos];
max[pos] += lazy[pos];
lazy[pos << 1] = lazy[pos << 1 | 1] = lazy[pos];
lazy[pos] = 0;
}
}
void build(int cur, int L, int R){
if(L > R) return;
if(L == R){
seg[cur] = p[L];
min[cur] = p[L];
max[cur] = p[L];
//printf("(%d, %d), (%lld, %lld, %lld)\n", L, R, seg[cur], min[cur], max[cur]);
return;
}
int mid = L + (R - L) / 2;
build(cur << 1, L, mid);
build(cur << 1 | 1, mid + 1, R);
push_up(cur);
//printf("(%d, %d), (%lld, %lld, %lld)\n", L, R, seg[cur], min[cur], max[cur]);
}
void maintain(int cur, int L, int R, int u, int v, ll value){
if(isOutside(L, R, u, v)) return;
int mid = L + (R - L) / 2;
if(isInside(L, R, u, v)){
lazy[cur] = value; return;
}
maintain(cur << 1, L, mid, u, v, value);
maintain(cur << 1 | 1, mid + 1, R, u, v, value);
}
ll query(int cur, int L, int R, int u, int v){
if(isOutside(L, R, u, v)) return 0;
int mid = L + (R - L) / 2;
push_down(cur, L, R);
if(isInside(L, R, u, v)) return seg[cur];
ll res = 0;
res += query(cur << 1, L, mid, u, v);
res += query(cur << 1 | 1, mid + 1, R, u, v);
return res;
}
ll max_query(int cur, int L, int R, int u, int v){
if(isOutside(L, R, u, v)) return 0;
int mid = L + (R - L) / 2;
push_down(cur, L, R);
if(isInside(L, R, u, v)) return max[cur];
ll res = 0;
res = Max(res, max_query(cur << 1, L, mid, u, v));
res = Max(res, max_query(cur << 1 | 1, mid + 1, R, u, v));
return res;
}
ll min_query(int cur, int L, int R, int u, int v){
if(isOutside(L, R, u, v)) return 1e9;
int mid = L + (R - L) / 2;
push_down(cur, L, R);
if(isInside(L, R, u, v)) return min[cur];
ll res = 1e9;
res = Min(res, min_query(cur << 1, L, mid, u, v));
res = Min(res, min_query(cur << 1 | 1, mid + 1, R, u, v));
return res;
}
}Seg;
int n, m;
Seg segment;
int main(void)
{
while(~scanf("%d%d", &n, &m)){
segment.clear();
for(int i = 1; i <= n; i++) scanf("%lld", &segment.p[i]);
segment.build(1, 1, n);
while(m--){
int u, v; scanf("%d%d", &u, &v);
//printf("(%lld, %lld)\n", segment.max_query(1, 1, n, u, v), segment.min_query(1, 1, n, u, v));
printf("%lld\n", segment.max_query(1, 1, n, u, v) - segment.min_query(1, 1, n, u, v));
}
}
return 0;
}