线段树(lazy标记)-- 模板

 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 }
原文地址:https://www.cnblogs.com/romaLzhih/p/9489839.html