线段树-区间加法模板

  1 /**\
  2 线段树:区间查询 区间修改
  3 input:
  4 5 5
  5 1 5 4 2 3
  6 2 2 4
  7 1 2 3 2
  8 2 3 4
  9 1 1 5 1
 10 2 1 4
 11 output:
 12 11
 13 8
 14 20
 15 \**/
 16 #include <bits/stdc++.h>
 17 using namespace std;
 18 #define fi first
 19 #define se second
 20 #define go continue
 21 #define int long long
 22 #define PII pair<int, int>
 23 #define sf(x) scanf("%lld",&x)
 24 #define ytz int _; sf(_); while(_--)
 25 #define fory(i,a,b) for(int i = a; i <= b; ++i)
 26 #define forl(i,a,b) for(int i = a; i >= b; --i)
 27 #define debug(a) cout << #a << " = " << a <<endl;
 28 /*---------------------------------------------*/
 29 int n, a[100010];
 30 struct node
 31 {
 32     int l, r, sum, lazy;
 33 };
 34 struct segment_tree
 35 {
 36     node t[100010 * 4];
 37     inline void init_lazy(int root)
 38     {
 39         t[root].lazy = 0;
 40     }
 41     inline void union_lazy(int p, int h)
 42     {
 43         t[h].lazy += t[p].lazy;
 44     }
 45     inline void cal_lazy(int root)
 46     {
 47         t[root].sum += (t[root].r - t[root].l + 1) * t[root].lazy;
 48     }
 49     inline void push_down(int root)
 50     {
 51         if(t[root].lazy != 0)
 52         {
 53             cal_lazy(root);
 54             if(t[root].l != t[root].r)
 55             {
 56                 int ch = root << 1;
 57                 union_lazy(root, ch);
 58                 union_lazy(root, ch + 1);
 59             }
 60             init_lazy(root);
 61         }
 62     }
 63     inline void push_up(int root)
 64     {
 65         int ch = root << 1;
 66         push_down(ch);
 67         push_down(ch + 1);
 68         t[root].sum = t[ch].sum + t[ch + 1].sum;
 69     }
 70     inline void build(int root, int l, int r)
 71     {
 72         t[root].l = l;
 73         t[root].r = r;
 74         init_lazy(root);
 75         if(l != r)
 76         {
 77             int mid = (l + r) >> 1;
 78             int ch = root << 1;
 79             build(ch, l, mid);
 80             build(ch + 1, mid + 1, r);
 81             push_up(root);
 82         }
 83         else
 84         {
 85             t[root].sum = a[l];
 86         }
 87     }
 88     inline void change(int root, int l, int r, int add)
 89     {
 90         push_down(root);
 91         if(t[root].l >= l && t[root].r <= r)
 92         {
 93             t[root].lazy = add;
 94             return;
 95         }
 96         int ch = root << 1;
 97         int mid = (t[root].l + t[root].r) >> 1;
 98         if(r <= mid) change(ch, l, r, add);
 99         else if(l > mid) change(ch + 1, l, r, add);
100         else
101         {
102             change(ch, l, mid, add);
103             change(ch + 1, mid + 1, r, add);
104         }
105         push_up(root);
106     }
107     inline int query(int root, int l, int r)
108     {
109         push_down(root);
110         if(t[root].l >= l && t[root].r <= r)
111         {
112             return t[root].sum;
113         }
114         int ch = root << 1;
115         int mid = (t[root].l + t[root].r) >> 1;
116         if(r <= mid) return query(ch, l, r);
117         else if(l > mid) return query(ch + 1, l, r);
118         else return query(ch, l, mid) + query(ch + 1, mid + 1, r);
119     }
120 } st;
121 int m;
122 signed main()
123 {
124     sf(n), sf(m);
125     fory(i, 1, n) sf(a[i]);
126     st.build(1, 1, n);
127     while(m--)
128     {
129         int op, x, y, z;
130         sf(op);
131         if(op == 1)
132         {
133             sf(x), sf(y), sf(z);
134             st.change(1, x, y, z);
135         }
136 
137         else
138         {
139             sf(x), sf(y);
140             printf("%lld\n", st.query(1, x, y));
141         }
142     }
143     return 0;
144 }

 

posted @ 2022-03-01 09:12  std&ice  阅读(49)  评论(0编辑  收藏  举报