线段树模板(支持所有操作,,累死我了
真的支持所有的操作,解释一下:
(算了还是直接在代码里看注释吧)
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 }