1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 template <class T> 7 inline void read(T &s) 8 { 9 s = 0; 10 int w = 1; 11 char ch = getchar(); 12 while (ch < '0' || ch > '9') 13 { 14 if (ch == '-') 15 w = -1; 16 ch = getchar(); 17 } 18 while (ch >= '0' && ch <= '9') 19 { 20 s = s * 10 + (ch ^ '0'); 21 ch = getchar(); 22 } 23 s *= w; 24 } 25 26 template <class T> 27 inline void write(T x) 28 { 29 if (x < 0) 30 { 31 putchar('-'); 32 x = -x; 33 } 34 if (x > 9) 35 write(x / 10); 36 putchar(x % 10 + '0'); 37 } 38 #define int long long 39 const int N = 1e5 + 7; 40 int n, m, a[N], ans[N << 2], tag[N << 2]; 41 inline int ls(int x) { return x << 1; } // 返回左儿子下标 2*i 42 inline int rs(int x) { return x << 1 | 1; } // 返回右儿子下标 2*i+1 43 inline void push_up(int pos) // 计算当前结点的值 44 { 45 ans[pos] = ans[ls(pos)] + ans[rs(pos)]; 46 } 47 void build(int p, int l, int r) 48 { 49 tag[p] = 0; 50 if (l == r) // 到达叶节点 51 { 52 ans[p] = a[l]; 53 return; 54 } 55 int mid = l + r >> 1; 56 build(ls(p), l, mid); // 建立左子树 57 build(rs(p), mid + 1, r); // 建立右子树 58 push_up(p); // 更新当前结点的值 59 } 60 inline void f(int p, int l, int r, int k) // 区间修改 + 打lazy标记 61 { 62 tag[p] = tag[p] + k; 63 ans[p] = ans[p] + k * (r - l + 1); 64 } 65 inline void push_down(int p, int l, int r) // 将当前结点的lazy标记下传 66 { 67 int mid = l + r >> 1; 68 f(ls(p), l, mid, tag[p]); 69 f(rs(p), mid + 1, r, tag[p]); 70 tag[p] = 0; 71 } 72 inline void update(int nl, int nr, int l, int r, int p, int k) // 更新区间 73 { 74 if (nl <= l && r <= nr) // [nl,l,r,nr] 当前区间被完全覆盖 75 { 76 ans[p] += k * (r - l + 1); 77 tag[p] += k; 78 return; 79 } 80 push_down(p, l, r); 81 int mid = l + r >> 1; 82 if (nl <= mid) // 若与左儿子有交集 83 update(nl, nr, l, mid, ls(p), k); 84 if (nr > mid) 85 update(nl, nr, mid + 1, r, rs(p), k); 86 push_up(p); 87 } 88 int query(int q_x, int q_y, int l, int r, int p) // 返回区间和 89 { 90 int res = 0; 91 if (q_x <= l && r <= q_y) 92 return ans[p]; 93 int mid = l + r >> 1; 94 push_down(p, l, r); 95 if (q_x <= mid) 96 res += query(q_x, q_y, l, mid, ls(p)); 97 if (q_y > mid) 98 res += query(q_x, q_y, mid + 1, r, rs(p)); 99 return res; 100 } 101 102 signed main() 103 { 104 // 输入 105 read(n), read(m); 106 for (int i = 1; i <= n; ++i) 107 read(a[i]); 108 build(1, 1, n); 109 while (m--) 110 { 111 int opt, x, y, k; 112 read(opt), read(x), read(y); 113 switch (opt) 114 { 115 case 1: 116 read(k); 117 update(x, y, 1, n, 1, k); 118 break; 119 case 2: 120 printf("%lld\n", query(x, y, 1, n, 1)); 121 break; 122 } 123 } 124 // system("pause"); 125 return 0; 126 }
标签:ch,洛谷,int,void,mid,tag,inline,P3372,模板 From: https://www.cnblogs.com/nijigasaki14/p/17847827.html