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 }