用于解决RMQ问题,即多次询问
#include <cstdio> const int MAXN = 100010; typedef long long LL; LL num[MAXN<<2]; LL tag[MAXN<<2]; inline void build(int o, int l, int r) { tag[o] = 0; if (l == r) { scanf("%d", &num[o]); return; } int mid = (l + r) >> 1; build(o<<1, l, mid); build(o<<1|1, mid+1, r); num[o] = num[o<<1] + num[o<<1|1]; } inline void pushdown(int x, int len) { if (tag[x]) { tag[x<<1] += tag[x]; tag[x<<1|1] += tag[x]; num[x<<1] += tag[x] * (len - (len>>1)); num[x<<1|1] += tag[x] * (len>>1); tag[x] = 0; } } inline void add(int o, int l, int r, int x, int y, int z) { if (x <= l && r <= y) { tag[o] += z; num[o] += (LL)z * (r - l + 1); return; } pushdown(o, r - l + 1); int mid = (l + r) >> 1; if (x <= mid) add(o<<1, l, mid, x, y, z); if (mid < y) add(o<<1|1, mid+1, r, x, y, z); num[o] = num[o<<1] + num[o<<1|1]; } inline LL query (int o, int l, int r, int x, int y) { //大括号不换行 if (x <= l && r <= y) { return num[o]; } pushdown(o, r - l + 1); LL ans = 0; int mid = (l + r) >> 1; if (x <= mid) ans += query(o<<1, l, mid, x, y); if (mid < y) ans += query(o<<1|1, mid+1, r, x, y); return ans; } int main() { int N,Q; scanf("%d%d", &N, &Q); build(1,1,N); int l,r; int OP; while (Q--) { scanf("%d", &OP); if(OP == 1) { int z; scanf("%d%d%d", &l, &r, &z); add(1, 1, N, l, r, z); } else { scanf("%d%d", &l, &r); printf("%lld\n", query(1, 1, N, l, r)); } } }