线段树2
Posted mrclr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树2相关的知识,希望对你有一定的参考价值。
这里发一下luogu线段树2的代码~~
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(‘ ‘) 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const int eps = 1e-8; 19 const int maxn = 1e5 + 5; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ‘ ‘; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - ‘0‘; ch = getchar();} 26 if(last == ‘-‘) ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) x = -x, putchar(‘-‘); 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + ‘0‘); 34 } 35 36 int n, m; 37 ll mod; 38 39 int l[maxn << 2], r[maxn << 2]; 40 ll sum[maxn << 2], lzy_add[maxn << 2], lzy_mul[maxn << 2]; 41 void build(int L, int R, int now) 42 { 43 l[now] = L; r[now] = R; 44 lzy_mul[now] = 1; 45 if(L == R) {sum[now] = read() % mod; return;} 46 int mid = (L + R) >> 1; 47 build(L, mid, now << 1); 48 build(mid + 1, R, now << 1 | 1); 49 sum[now] = (sum[now << 1] + sum[now << 1 | 1]) % mod; 50 } 51 void pushdown(int now) 52 { 53 if(lzy_mul[now] != 1) 54 { 55 (lzy_mul[now << 1] *= lzy_mul[now]) %= mod; 56 (lzy_mul[now << 1 | 1] *= lzy_mul[now]) %= mod; 57 (lzy_add[now << 1] *= lzy_mul[now]) %= mod; 58 (lzy_add[now << 1 | 1] *= lzy_mul[now]) %= mod; 59 (sum[now << 1] *= lzy_mul[now]) %= mod; 60 (sum[now << 1 | 1] *= lzy_mul[now]) %= mod; 61 lzy_mul[now] = 1; 62 } 63 if(lzy_add[now]) 64 { 65 (lzy_add[now << 1] += lzy_add[now]) %= mod; 66 (lzy_add[now << 1 | 1] += lzy_add[now]) %= mod; 67 (sum[now << 1] += lzy_add[now] * (r[now << 1] - l[now << 1] + 1)) %= mod; 68 (sum[now << 1 | 1] += lzy_add[now] * (r[now << 1 | 1] - l[now << 1 | 1] + 1)) %= mod; 69 lzy_add[now] = 0; 70 } 71 } 72 void update(int L, int R, int now, ll d, bool flag) 73 { 74 if(l[now] == L && r[now] == R) 75 { 76 if(flag) sum[now] += d * (R - L + 1), lzy_add[now] += d; 77 else sum[now] *= d, lzy_add[now] *= d, lzy_mul[now] *= d; 78 sum[now] %= mod; lzy_add[now] %= mod; lzy_mul[now] %= mod; 79 return; 80 } 81 pushdown(now); 82 int mid = (l[now] + r[now]) >> 1; 83 if(R <= mid) update(L, R, now << 1, d, flag); 84 else if(L > mid) update(L, R, now << 1 | 1, d, flag); 85 else update(L, mid, now << 1, d, flag), update(mid + 1, R, now << 1 | 1, d, flag); 86 sum[now] = (sum[now << 1] + sum[now << 1 | 1]) % mod; 87 } 88 ll query(int L, int R, int now) 89 { 90 if(l[now] == L && r[now] == R) return sum[now] % mod; 91 pushdown(now); 92 int mid = (l[now] + r[now]) >> 1; 93 if(R <= mid) return query(L, R, now << 1); 94 else if(L > mid) return query(L, R, now << 1 | 1); 95 else return (query(L, mid, now << 1) + query(mid + 1, R, now << 1 | 1)) % mod; 96 } 97 98 int main() 99 { 100 n = read(); mod = read(); 101 build(1, n, 1); 102 m = read(); 103 for(int i = 1; i <= m; ++i) 104 { 105 int d = read(), L = read(), R = read(); 106 if(d == 1) 107 { 108 ll c = read(); 109 update(L, R, 1, c, 0); 110 } 111 else if(d == 2) 112 { 113 ll c = read(); 114 update(L, R, 1, c, 1); 115 } 116 else write(query(L, R, 1)), enter; 117 } 118 return 0; 119 }
以上是关于线段树2的主要内容,如果未能解决你的问题,请参考以下文章