详解:https://blog.csdn.net/yitongjun/article/details/53193724
一、区间操作,只有add
1 #define MID(l, r) ((l) + ((r) - (l)) / 2) 2 #define lson(o) ((o)<<1) 3 #define rson(o) ((o)<<1|1) 4 typedef long long ll; 5 const int maxn = 1e5 + 10; 6 struct node 7 { 8 int l, r; 9 ll sum, add, mmax, mmin; 10 }tree[maxn * 4]; 11 ll a[maxn]; 12 void pushup(int o) 13 { 14 int lc = lson(o), rc = rson(o); 15 tree[o].sum = tree[lc].sum + tree[rc].sum; 16 tree[o].mmax = max(tree[lc].mmax, tree[rc].mmax); 17 tree[o].mmin = min(tree[lc].mmin, tree[rc].mmin); 18 } 19 void build(int o, int l, int r) 20 { 21 tree[o].l = l; 22 tree[o].r = r; 23 if(l == r) 24 { 25 tree[o].mmax = tree[o].mmin = tree[o].add = tree[o].sum = a[l]; 26 return; 27 } 28 int m = MID(l, r); 29 build(lson(o), l, m); 30 build(rson(o), m + 1, r); 31 pushup(o); 32 //printf("%d %d %d %lld %lld %lld\n", o, l, r, tree[o].add, tree[o].sum, tree[o].mmax); 33 } 34 35 void maintain(int o) 36 { 37 tree[o].mmax = tree[o].mmin = tree[o].sum = 0;//根节点的值存储在add内 38 if(tree[o].r > tree[o].l) 39 { 40 pushup(o); 41 } 42 tree[o].mmin += tree[o].add; 43 tree[o].mmax += tree[o].add; 44 tree[o].sum += tree[o].add * (tree[o].r - tree[o].l + 1); 45 } 46 47 ///[ql, qr] 加上 v 48 int ql, qr; 49 ll v; 50 void update(int o) 51 { 52 if(ql <= tree[o].l && qr >= tree[o].r)tree[o].add += v; 53 else 54 { 55 int m = MID(tree[o].l, tree[o].r); 56 if(ql <= m)update(lson(o)); 57 if(qr > m)update(rson(o)); 58 } 59 maintain(o); 60 } 61 62 ll sum, mmax, mmin; 63 ///[ql, qr]查询 64 /*void query_init() 65 { 66 sum = 0; 67 mmax = -INF; 68 mmin = INF; 69 }*/ 70 void query(int o, ll add) 71 { 72 //DEBUG(o); 73 if(ql <= tree[o].l && qr >= tree[o].r) 74 { 75 sum += tree[o].sum + add * (tree[o].r - tree[o].l + 1); 76 mmin = min(mmin, tree[o].mmin + add); 77 mmax = max(mmax, tree[o].mmax + add); 78 } 79 else 80 { 81 int m = MID(tree[o].l, tree[o].r); 82 if(ql <= m)query(lson(o), add + tree[o].add); 83 if(qr > m)query(rson(o), add + tree[o].add); 84 } 85 }