毕生所学。
1 const int N = 2e5 + 10; 2 #define lson rt << 1 // == rt * 2 左儿子 3 #define rson rt << 1 | 1 // == rt * 2 + 1 右儿子 4 #define int_mid int mid = tree[rt].l + tree[rt].r >> 1 5 int a[N]; // 初始值 6 struct node { 7 int l, r; 8 ll val, lazy; 9 } tree[N * 4]; 10 void push_up(int rt) { 11 //tree[rt].val = min(tree[lson].val, tree[rson].val); 12 //tree[rt].val = max(tree[lson].val, tree[rson].val); 13 tree[rt].val = tree[lson].val + tree[rson].val; 14 } 15 void push_down(int rt) { 16 if (tree[rt].lazy) { 17 tree[lson].lazy += tree[rt].lazy; 18 tree[rson].lazy += tree[rt].lazy; 19 //{ // 维护最大最小值 20 // tree[lson].val += tree[rt].lazy; 21 // tree[rson].val += tree[rt].lazy; 22 //} 23 { // 维护和 24 int l = tree[rt].l, r = tree[rt].r; 25 int mid = l + r >> 1; 26 tree[lson].val += 1ll * (mid - l + 1) * tree[rt].lazy; 27 tree[rson].val += 1ll * (r - mid) * tree[rt].lazy; 28 } 29 tree[rt].lazy = 0; 30 } 31 } 32 void build(int rt, int l, int r) { // 建树 33 tree[rt].l = l, tree[rt].r = r; 34 tree[rt].lazy = 0; 35 if (l == r) { 36 tree[rt].val = a[l]; // 给定一个初始值 37 return; 38 } else { 39 int mid = l + r >> 1; // (l + r) / 2 40 build(lson, l, mid); 41 build(rson, mid + 1, r); 42 push_up(rt); 43 } 44 } 45 46 void update_point(int rt, int pos, ll val) { // 单点更新 47 if (tree[rt].l == tree[rt].r && pos == tree[rt].l) { 48 tree[rt].val += val; 49 return; 50 } 51 int_mid; 52 if (pos <= mid) update_point(lson, pos, val); 53 else update_point(rson, pos, val); 54 push_up(rt); 55 } 56 57 void update_interval(int rt, int l, int r, ll val) { // 区间更新 58 if (l <= tree[rt].l && r >= tree[rt].r) { 59 tree[rt].lazy += val; 60 //tree[rt].val += val; // 维护最大最小值 61 tree[rt].val += 1ll * (tree[rt].r - tree[rt].l + 1) * val; // 维护和 62 return; 63 } 64 push_down(rt); 65 int_mid; 66 if (l <= mid) update_interval(lson, l, r, val); 67 if (r > mid) update_interval(rson, l, r, val); 68 push_up(rt); 69 } 70 71 ll query_point(int rt, int pos) { // 单点查询 72 if (tree[rt].l == tree[rt].r && tree[rt].l == pos) 73 return tree[rt].val; 74 push_down(rt); 75 int_mid; 76 if (pos <= mid) query_point(lson, pos); 77 else query_point(rson, pos); 78 } 79 80 ll query_interval(int rt, int l, int r) { // 区间查询 81 if (l <= tree[rt].l && r >= tree[rt].r) 82 return tree[rt].val; 83 push_down(rt); 84 int_mid; 85 if (r <= mid) return query_interval(lson, l, r); 86 else if (l > mid) return query_interval(rson, l, r); 87 else { 88 //return min(query_interval(lson, l, mid), query_interval(rson, mid + 1, r)); 89 //return max(query_interval(lson, l, mid), query_interval(rson, mid + 1, r)); 90 return query_interval(lson, l, mid) + query_interval(rson, mid + 1, r); 91 } 92 }