1 int a[MAXN], ans[MAXN << 2], lazy[MAXN << 2]; 2 void PushUp(int rt) { 3 ans[rt] = ans[rt << 1] + ans[rt << 1 | 1]; 4 } 5 void PushDown(int rt, int ln, int rn) { //ln表示左子树元素结点个数,rn表示右子树结点个数 6 if (lazy[rt]) { 7 lazy[rt << 1] += lazy[rt]; 8 lazy[rt << 1 | 1] += lazy[rt]; 9 ans[rt << 1] += lazy[rt] * ln; 10 ans[rt << 1 | 1] += lazy[rt] * rn; 11 lazy[rt] = 0; 12 } 13 } 14 //建树Build(1,n,1) 15 void Build(int l, int r, int rt) { 16 if (l == r) { 17 ans[rt] = a[l]; 18 return; 19 } 20 int mid = (l + r) >> 1; 21 Build(l, mid, rt << 1); 22 Build(mid + 1, r, rt << 1 | 1); 23 PushUp(rt); 24 } 25 //点更新Add(L,C,1,n,1) 26 void Add(int L, int C, int l, int r, int rt) { 27 if (l == r) { 28 ans[rt] += C; 29 return; 30 } 31 int mid = (l + r) >> 1; 32 //PushDown(rt,mid-l+1,r-mid); 若既有点更新又有区间更新,需要这句话 33 if (L <= mid) 34 Add(L, C, l, mid, rt << 1); 35 else 36 Add(L, C, mid + 1, r, rt << 1 | 1); 37 PushUp(rt); 38 } 39 //区间更新Upadate(L,R,C,1,n,1) 40 void Update(int L, int R, int C, int l, int r, int rt) { 41 if (L <= l && r <= R) { 42 ans[rt] += C * (r - l + 1); 43 lazy[rt] += C; 44 return; 45 } 46 int mid = (l + r) >> 1; 47 PushDown(rt, mid - l + 1, r - mid); 48 if (L <= mid) 49 Update(L, R, C, l, mid, rt << 1); 50 if (R > mid) 51 Update(L, R, C, mid + 1, r, rt << 1 | 1); 52 PushUp(rt); 53 } 54 //区间查询Query(L,R,1,n,1) 55 LL Query_sum(int L, int R, int l, int r, int rt) { 56 if (L <= l && r <= R) 57 return ans[rt]; 58 int mid = (l + r) >> 1; 59 PushDown(rt, mid - l + 1, r - mid); //若更新只有点更新,不需要这句 60 LL ANS = 0; 61 if (L <= mid) 62 ANS += Query_sum(L, R, l, mid, rt << 1); 63 if (R > mid) 64 ANS += Query_sum(L, R, mid + 1, r, rt << 1 | 1); 65 return ANS; 66 } 67 //区间最大值 68 int Query_max(int L, int R, int l, int r, int rt) { 69 if (L <= l&&R <= r) 70 return ans[rt]; 71 int mid = (l + r) >> 1; 72 PushDown(rt, mid - l + 1, r - mid); 73 int ANS = 0; 74 if (L <= mid) ANS = max(ANS, Query_max(L, R, l, mid, rt << 1)); 75 if (R > mid) ANS = max(ANS, Query_max(L, R, mid + 1, r, rt << 1 | 1)); 76 return ANS; 77 } 78 //单点查询 79 int Query(int L, int R, int l, int r, int rt) { 80 if (L == l&&R == r) 81 return ans[rt]; 82 int mid = (l + r) >> 1; 83 PushDown(rt, mid - l + 1, r - mid); 84 int ANS = 0; 85 if (L <= mid) 86 ANS = Query(L, R, l, mid, rt << 1); 87 if (R > mid) 88 ANS = Query(L, R, mid + 1, r, rt << 1 | 1); 89 return ANS; 90 }