P3373 【模板】线段树 2
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e5+5; 5 ll a[maxn], add[maxn*4], mul[maxn*4], sum[maxn*4]; 6 ll n, m, p; 7 void pushup(int rt) { 8 sum[rt] = (sum[rt*2]+sum[rt*2+1])%p; 9 } 10 void pushdown(int rt, int l, int r) { 11 int mid = (l+r)/2; 12 sum[rt*2] = (sum[rt*2]*mul[rt]+add[rt]*(mid-l+1))%p; 13 sum[rt*2+1] = (sum[rt*2+1]*mul[rt]+add[rt]*(r-mid))%p; 14 mul[rt*2] = (mul[rt*2]*mul[rt])%p; 15 mul[rt*2+1] = (mul[rt*2+1]*mul[rt])%p; 16 add[rt*2] = (add[rt*2]*mul[rt]+add[rt])%p; 17 add[rt*2+1] = (add[rt*2+1]*mul[rt]+add[rt])%p; 18 19 mul[rt] = 1; 20 add[rt] = 0; 21 } 22 void build(int l, int r, int rt) { 23 add[rt] = 0; 24 mul[rt] = 1; 25 if (l == r) { 26 sum[rt] = a[l]%p; 27 return; 28 } 29 int mid = (l+r)/2; 30 build(l,mid,rt*2); 31 build(mid+1,r,rt*2+1); 32 pushup(rt); 33 } 34 void update1(int be, int ed, int val, int l, int r, int rt) { 35 if (be <= l && r <= ed) { 36 add[rt] = (add[rt]*val)%p; 37 mul[rt] = (mul[rt]*val)%p; 38 sum[rt] = (sum[rt]*val)%p; 39 return; 40 } 41 pushdown(rt,l,r); 42 int mid = (l+r)/2; 43 if (be <= mid) update1(be,ed,val,l,mid,rt*2); 44 if (ed > mid) update1(be,ed,val,mid+1,r,rt*2+1); 45 pushup(rt); 46 } 47 void update2(int be, int ed, int val, int l, int r, int rt) { 48 if (be <= l && r <= ed) { 49 add[rt] = (add[rt]+val)%p; 50 sum[rt] = (sum[rt]+val*(r-l+1))%p; 51 return; 52 } 53 pushdown(rt,l,r); 54 int mid = (l+r)/2; 55 if (be <= mid) update2(be,ed,val,l,mid,rt*2); 56 if (ed > mid) update2(be,ed,val,mid+1,r,rt*2+1); 57 pushup(rt); 58 } 59 ll query(int be, int ed, int l, int r, int rt) { 60 if (be <= l && r <= ed) { 61 return sum[rt]; 62 } 63 pushdown(rt,l,r); 64 ll res = 0; int mid = (l+r)/2; 65 if (be <= mid) res = (res+query(be,ed,l,mid,rt*2))%p; 66 if (ed > mid) res = (res+query(be,ed,mid+1,r,rt*2+1))%p; 67 return res; 68 } 69 int main() { 70 scanf("%d%d",&n,&m); scanf("%lld",&p); 71 for (int i = 1; i <= n; i++) scanf("%lld",&a[i]); 72 build(1,n,1); 73 while (m--) { 74 int op, x, y; scanf("%d%d%d",&op,&x,&y); 75 if (op == 1) { 76 int k; scanf("%d",&k); 77 update1(x,y,k,1,n,1); 78 } 79 else if (op == 2) { 80 int k; scanf("%d",&k); 81 update2(x,y,k,1,n,1); 82 } 83 else { 84 ll ans = query(x,y,1,n,1); 85 printf("%lld\n",ans); 86 } 87 } 88 return 0; 89 }
分块,学习了各种玄学卡常数的操作
1 #include <bits/stdc++.h> 2 #define rg register 3 using namespace std; 4 typedef long long ll; 5 const int maxn = 1e5+5; 6 char buf[70000000]; 7 int n, m, cnt = 0; 8 int pos[maxn], L[maxn], R[maxn]; 9 ll a[maxn], add[maxn], mul[maxn], sum[maxn]; 10 ll block, val, mod; 11 template<typename T> inline T read(T a) { 12 T res = 0, f = 1; 13 char ch = buf[cnt++]; 14 while (!isdigit(ch)) { 15 if (ch == '-') f = -1; 16 ch = buf[cnt++]; 17 } 18 while (isdigit(ch)) { 19 res = (res<<3)+(res<<1)+ch-48; 20 ch = buf[cnt++]; 21 } 22 return res*f; 23 } 24 template<typename T> inline void write(T x) { 25 if (x < 0) { 26 putchar('-'); 27 write(-x); 28 return; 29 } 30 if (x > 9) write(x/10); 31 putchar(x%10+48); 32 } 33 inline void reset(int x) { 34 for (int i = L[x]; i <= R[x]; ++i) 35 a[i] = (a[i]*mul[x]+add[x])%mod; 36 add[x] = 0, mul[x] = 1; 37 } 38 inline void Add(int l, int r, ll val) { 39 int p = pos[l], q = pos[r]; 40 if (p == q) { 41 reset(p); 42 sum[p] = (sum[p]+(r-l+1)*val)%mod; 43 for (int i = l; i <= r; ++i) 44 a[i] += val; 45 } 46 else { 47 reset(p); 48 sum[p] = (sum[p]+(R[p]-l+1)*val)%mod; 49 for (int i = l; i <= R[p]; ++i) 50 a[i] += val; 51 52 reset(q); 53 sum[q] = (sum[q]+(r-L[q]+1)*val)%mod; 54 for (int i = L[q]; i <= r; ++i) 55 a[i] += val; 56 57 for (int i = p+1; i <= q-1; ++i) { 58 add[i] += val; 59 sum[i] = (sum[i]+block*val)%mod; 60 } 61 } 62 } 63 inline void Mul(int l, int r, ll val) { 64 int p = pos[l], q = pos[r]; 65 if (p == q) { 66 reset(p); 67 for (int i = l; i <= r; ++i) { 68 sum[p] += (val-1)*a[i]%mod; 69 a[i] *= val, a[i] %= mod; 70 } 71 for (int i = p+1; i <= q-1; ++i) { 72 mul[i] *= val, mul[i] %= mod; 73 add[i] *= val, add[i] %= mod; 74 sum[i] *= val, sum[i] %= mod; 75 } 76 } 77 else { 78 reset(p); 79 for (int i = l; i <= R[p]; ++i) { 80 sum[p] += (val-1)*a[i]%mod; 81 a[i] *= val, a[i] %= mod; 82 } 83 reset(q); 84 for (int i = L[q]; i <= r; ++i) { 85 sum[q] += (val-1)*a[i]%mod; 86 a[i] *= val, a[i] %= mod; 87 } 88 for (int i = p+1; i <= q-1; ++i) { 89 mul[i] *= val, mul[i] %= mod; 90 add[i] *= val, add[i] %= mod; 91 sum[i] *= val, sum[i] %= mod; 92 } 93 } 94 } 95 ll query(int l, int r) { 96 ll ans = 0; 97 int p = pos[l], q = pos[r]; 98 if (p == q) { 99 for (int i = l; i <= r; ++i) 100 ans += (a[i]*mul[p] + add[p])%mod; 101 } 102 else { 103 for (int i = l; i <= R[p]; ++i) 104 ans += (a[i]*mul[p] + add[p])%mod; 105 106 for (int i = L[q]; i <= r; ++i) 107 ans += (a[i]*mul[q] + add[q])%mod; 108 109 for (int i = p+1; i <= q-1; ++i) 110 ans += sum[i]; 111 } 112 return ans; 113 } 114 int main() { 115 fread(buf,1,70000000,stdin); 116 n = read(n), m = read(m), mod = read(mod); 117 block = sqrt(n); 118 for (rg int i = 1; i <= n; ++i) pos[i] = i/block; 119 for (rg int i = n; i >= 1; --i) L[pos[i]] = i; 120 for (rg int i = 1; i <= n; ++i) R[pos[i]] = i; 121 for (rg int i = 1; i <= n; ++i) a[i] = read(a[i]); 122 for (rg int i = 1; i <= n; ++i) sum[pos[i]] += a[i]; 123 for (rg int i = pos[1]; i <= pos[n]; ++i) mul[i] = 1; 124 125 for (int i = 1; i <= m; ++i) { 126 int op, l, r; 127 op = read(op), l = read(l), r = read(r); 128 if (op == 1) { 129 val = read(val); 130 Mul(l,r,val); 131 } 132 else if (op == 2) { 133 val = read(val); 134 Add(l,r,val); 135 } 136 else { 137 write(query(l,r)%mod); 138 putchar('\n'); 139 } 140 } 141 }