线段树模板(支持所有操作,,累死我了

真的支持所有的操作,解释一下:

(算了还是直接在代码里看注释吧)

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 typedef long long ll;
  6 
  7 inline ll read() {
  8     ll x = 0 , f = 1; char ch = getchar();
  9     for ( ; !isdigit(ch) ; ch = getchar()) if (ch == '-') f = -1;
 10     for ( ; isdigit(ch) ; ch = getchar()) x = x * 10 + ch - '0';
 11     return x * f;
 12 }
 13 
 14 const ll maxn = 1e5 + 1;
 15 const ll mod = LLONG_MAX;
 16 
 17 struct SegTree {
 18     ll leftSon , rightSon , weight , LazyTagAdd , LazyTagMul , Max , Min;
 19 }segTree[maxn << 2];
 20 
 21 inline void pushUp(ll root) {
 22     segTree[root].weight = (segTree[root << 1].weight + segTree[root << 1 | 1].weight) % mod;
 23     segTree[root].Max = max(segTree[root << 1].Max , segTree[root << 1 | 1].Max) % mod;
 24     segTree[root].Min = min(segTree[root << 1].Min , segTree[root << 1 | 1].Min) % mod;
 25 }
 26 
 27 inline void pushDown(ll root) {
 28     segTree[root << 1].weight *= segTree[root].LazyTagMul;
 29     segTree[root << 1].weight %= mod;
 30     
 31     segTree[root << 1].LazyTagAdd *= segTree[root].LazyTagMul;
 32     segTree[root << 1].LazyTagAdd %= mod;
 33     
 34     segTree[root << 1].LazyTagMul *= segTree[root].LazyTagMul;
 35     segTree[root << 1].LazyTagMul %= mod;
 36     
 37     segTree[root << 1].Max *= segTree[root].LazyTagMul;
 38     segTree[root << 1].Max %= mod;
 39     
 40     segTree[root << 1].Min *= segTree[root].LazyTagMul;
 41     segTree[root << 1].Min %= mod;
 42     
 43     
 44     segTree[root << 1 | 1].weight *= segTree[root].LazyTagMul;
 45     segTree[root << 1 | 1].weight %= mod;
 46     
 47     segTree[root << 1 | 1].LazyTagAdd *= segTree[root].LazyTagMul;
 48     segTree[root << 1 | 1].LazyTagAdd %= mod;
 49     
 50     segTree[root << 1 | 1].LazyTagMul *= segTree[root].LazyTagMul;
 51     segTree[root << 1 | 1].LazyTagMul %= mod;
 52     
 53     segTree[root << 1 | 1].Max *= segTree[root].LazyTagMul;
 54     segTree[root << 1 | 1].Max %= mod;
 55     
 56     segTree[root].LazyTagMul = 1;
 57     
 58     segTree[root << 1].LazyTagAdd += segTree[root].LazyTagAdd;
 59     segTree[root << 1].LazyTagAdd %= mod;
 60     
 61     segTree[root << 1 | 1].LazyTagAdd += segTree[root].LazyTagAdd;
 62     segTree[root << 1 | 1].LazyTagAdd %= mod;
 63     
 64     segTree[root << 1].weight += segTree[root].LazyTagAdd * (segTree[root << 1].rightSon - segTree[root << 1].leftSon + 1);
 65     segTree[root << 1].weight %= mod;
 66     
 67     segTree[root << 1 | 1].weight += segTree[root].LazyTagAdd * (segTree[root << 1 | 1].rightSon - segTree[root << 1 | 1].leftSon + 1);
 68     segTree[root << 1 | 1].weight %= mod;
 69     
 70     segTree[root << 1].Max += segTree[root].LazyTagAdd;
 71     segTree[root << 1].Max %= mod;
 72     segTree[root << 1].Min += segTree[root].LazyTagAdd;
 73     segTree[root << 1].Min %= mod;
 74     
 75     segTree[root << 1 | 1].Max += segTree[root].LazyTagAdd;
 76     segTree[root << 1 | 1].Max %= mod;
 77     segTree[root << 1 | 1].Min += segTree[root].LazyTagAdd;
 78     segTree[root << 1 | 1].Min %= mod;
 79     
 80     segTree[root].LazyTagAdd = 0;
 81     return ;
 82 }
 83 
 84 void build(ll root , ll _left , ll _right) {//建树
 85     segTree[root].leftSon = _left , segTree[root].rightSon = _right , segTree[root].LazyTagAdd = 0 , segTree[root].LazyTagMul = 1;
 86     
 87     if (_left == _right) {
 88         segTree[root].weight = segTree[root].Max = segTree[root].Min = read();
 89         return ;
 90     }
 91     
 92     ll _mid = (_left + _right) >> 1;
 93     build(root << 1 , _left , _mid);
 94     build(root << 1 | 1 , _mid + 1 , _right);
 95     
 96     pushUp(root);
 97 }
 98 
 99 ll querySum(ll root , ll _left , ll _right) {//查询区间和
100     if (segTree[root].rightSon < _left || _right < segTree[root].leftSon) {
101         return 0;
102     }
103     //cout << root << " " << segTree[root].leftSon << " " << segTree[root].rightSon << " " << segTree[root].weight << endl;
104     if (_left <= segTree[root].leftSon && segTree[root].rightSon <= _right) {
105         return segTree[root].weight % mod;
106     }
107     
108     
109     if (segTree[root].LazyTagAdd || segTree[root].LazyTagMul != 1) {
110         pushDown(root);
111     }
112     
113     ll _mid = ((segTree[root].leftSon + segTree[root].rightSon) >> 1) , ans = 0;
114     if (_left <= _mid) {
115         ans += querySum(root << 1 , _left , _right);
116         ans %= mod;
117     }
118     if (_mid < _right) {
119         ans += querySum(root << 1 | 1 , _left , _right);
120         ans %= mod;
121     }
122     
123     return ans;
124 } 
125 
126 void addNum(ll root , ll _left , ll _right , ll add) {//区间加法
127     if (segTree[root].rightSon < _left || _right < segTree[root].leftSon) {
128         return ;
129     }
130     
131     if (_left <= segTree[root].leftSon && segTree[root].rightSon <= _right) {
132         segTree[root].weight += (segTree[root].rightSon - segTree[root].leftSon + 1) * add;
133         segTree[root].weight %= mod;
134         
135         segTree[root].LazyTagAdd += add;
136         segTree[root].LazyTagAdd %= mod;
137         
138         segTree[root].Max += add;
139         segTree[root].Max %= mod;
140         
141         segTree[root].Min += add;
142         segTree[root].Min %= mod;
143         return ;
144     }
145     
146     if (segTree[root].LazyTagAdd || segTree[root].LazyTagMul != 1) {
147         pushDown(root);
148     }
149     
150     ll _mid = (segTree[root].leftSon + segTree[root].rightSon) >> 1;
151     if (_left <= _mid) {
152         addNum(root << 1 , _left , _right , add);
153     }
154     if (_mid < _right) {
155         addNum(root << 1 | 1 , _left , _right , add);
156     }
157     
158     pushUp(root);
159     
160     return ;
161 }
162 
163 void mulNum(ll root , ll _left , ll _right , ll mul) {//区间乘法
164     if (segTree[root].rightSon < _left || _right < segTree[root].leftSon) {
165         return ;
166     }
167     
168     if (_left <= segTree[root].leftSon && segTree[root].rightSon <= _right) {
169         segTree[root].weight *= mul;
170         segTree[root].weight %= mod;
171         
172         segTree[root].LazyTagAdd *= mul;
173         segTree[root].LazyTagAdd %= mod;
174         
175         segTree[root].LazyTagMul *= mul;
176         segTree[root].LazyTagMul %= mod;
177         
178         segTree[root].Max *= mul;
179         segTree[root].Max %= mod;
180         
181         segTree[root].Min *= mul;
182         segTree[root].Min %= mod;
183         return ;
184     }
185     
186     if (segTree[root].LazyTagAdd || segTree[root].LazyTagMul != 1) {
187         pushDown(root);
188     }
189     
190     ll _mid = (segTree[root].leftSon + segTree[root].rightSon) >> 1;
191     if (_left <= _mid) {
192         mulNum(root << 1 , _left , _right , mul);
193     }
194     if (_mid < _right) {
195         mulNum(root << 1 | 1 , _left , _right , mul);
196     }
197     
198     pushUp(root);
199     
200     return ;
201 }
202 
203 ll queryMax(ll root , ll _left , ll _right) {//区间最大值(其实不如去写st表,比这玩意好写多了)
204     if (segTree[root].rightSon < _left || _right < segTree[root].leftSon) {
205         return -LLONG_MAX;
206     }
207     
208     if (_left <= segTree[root].leftSon && segTree[root].rightSon <= _right) {
209         return segTree[root].Max;
210     }
211     
212     if (segTree[root].LazyTagAdd || segTree[root].LazyTagMul != 1) {
213         pushDown(root);
214     }
215     
216     ll _mid = ((segTree[root].leftSon + segTree[root].rightSon) >> 1) , ans = -LLONG_MAX;
217     if (_left <= _mid) {
218         ans = max(ans , queryMax(root << 1 , _left , _right));
219         ans %= mod;
220     }
221     if (_mid < _right) {
222         ans = max(ans , queryMax(root << 1 | 1 , _left , _right));
223         ans %= mod;
224     }
225     
226     return ans;
227 }
228 
229 ll queryMin(ll root , ll _left , ll _right) {//区间最小值
230     if (segTree[root].rightSon < _left || _right < segTree[root].leftSon) {
231         return LLONG_MAX;
232     }
233     
234     if (_left <= segTree[root].leftSon && segTree[root].rightSon <= _right) {
235         return segTree[root].Min;
236     }
237     
238     if (segTree[root].LazyTagAdd || segTree[root].LazyTagMul != 1) {
239         pushDown(root);
240     }
241     
242     ll _mid = ((segTree[root].leftSon + segTree[root].rightSon) >> 1) , ans = LLONG_MAX;
243     if (_left <= _mid) {
244         ans = min(ans , queryMin(root << 1 , _left , _right));
245         ans %= mod;
246     }
247     if (_mid < _right) {
248         ans = min(ans , queryMin(root << 1 | 1 , _left , _right));
249         ans %= mod;
250     }
251     
252     return ans;
253 }
254 
255 ll n , m;
256 
257 int main() {
258     n = read() , m = read();
259     
260     build(1 , 1 , n);
261     
262     for (ll i = 1 ; i <= m ; i ++) {
263         ll opr = read();
264         if (opr == 1) {
265             ll x = read() , y = read() , z = read();
266             addNum(1 , x , y , z);
267         }
268         else if (opr == 2) {
269             ll x = read() , y = read();
270             printf("%lld\n" , queryMax(1 , x , y));
271         }
272         else if (opr == 3) {
273             ll x = read() , y = read();
274             printf("%lld\n" , queryMin(1 , x , y));
275         }
276     } 
277 }

 

posted @ 2018-08-27 20:26  Avrora  阅读(291)  评论(0编辑  收藏  举报