简单版本:
1 #include <bits/stdc++.h> 2 #define pi acos(-1) 3 using namespace std; 4 typedef long long LL; 5 typedef pair<int, int> P; 6 const int INF = 0x3f3f3f3f; 7 const LL ll_INF = 0x3f3f3f3f3f3f3f3f; 8 const int MAXN = 1e5 + 10; 9 const int mod = 1e9 + 7; 10 11 #define maxn 100007 //元素总个数 12 #define ls l,m,rt<<1 13 #define rs m+1,r,rt<<1|1 14 LL sum[maxn<<2], add[maxn<<2]; 15 LL a[maxn]; 16 int n, m; 17 18 void PushUp(int rt) { sum[rt] = sum[rt<<1]+sum[rt<<1|1]; } 19 void PushDown(int rt, int ln, int rn) 20 { 21 if(add[rt]){ 22 add[rt<<1] += add[rt]; 23 add[rt<<1|1] += add[rt]; 24 sum[rt<<1] += add[rt]*ln; 25 sum[rt<<1|1] += add[rt]*rn; 26 add[rt]=0; 27 } 28 } 29 void Build(int l, int r, int rt) 30 { 31 if(l==r){ 32 sum[rt]=a[l]; 33 return; 34 } 35 int mid = (l+r)>>1; 36 Build(l, mid, rt<<1); 37 Build(mid+1, r, rt<<1|1); 38 PushUp(rt); 39 } 40 41 //点的更新,假设A[L]+=C 42 void update(int L, LL C, int l, int r, int rt) 43 { 44 if(l==r){ 45 sum[rt]+=C; 46 return; 47 } 48 int mid = (l+r)>>1; 49 PushDown(rt, mid-l+1, r-mid); 50 if(L <= mid) update(L, C, l, mid, rt<<1); 51 else update(L, C, mid+1, r, rt<<1|1); 52 PushUp(rt); 53 } 54 55 //区间更新,假设A[L,R]+=C 56 void update(int L, int R, LL C, int l, int r, int rt) 57 { 58 if(L<=l && r<=R){ 59 sum[rt]+=C*(r-l+1); 60 add[rt]+=C; 61 return ; 62 } 63 int mid = (l+r)>>1; 64 PushDown(rt, mid-l+1, r-mid); 65 if(L <= mid) update(L, R, C, l, mid, rt<<1); 66 if(R > mid) update(L, R, C, mid+1, r, rt<<1|1); 67 PushUp(rt); 68 } 69 70 //区间查询 71 LL Query(int L, int R, int l, int r, int rt) 72 { 73 if(L<=l && r<=R){ 74 return sum[rt]; 75 } 76 int mid = (l+r)>>1; 77 PushDown(rt, mid-l+1, r-mid); 78 LL ans=0; 79 if(L<=mid) ans += Query(L, R, l, mid, rt<<1); 80 if(R> mid) ans += Query(L, R, mid+1, r, rt<<1|1); 81 return ans; 82 } 83 84 int main() 85 { 86 scanf("%d%d", &n, &m); 87 int flag, x, y; 88 LL k; 89 for(int i=1; i<=n; i++) scanf("%lld", &a[i]); 90 Build(1, n, 1); 91 for(int i=1; i<=m; i++) { 92 scanf("%d", &flag); 93 if(flag==1){ 94 scanf("%d%d%lld", &x, &y, &k); 95 update(x, y, k, 1, n, 1); 96 } 97 else if(flag==2){ 98 scanf("%d%d", &x, &y); 99 printf("%lld ", Query(x, y, 1, n, 1)); 100 } 101 } 102 }
复杂版本(带lazy)
1 #include <bits/stdc++.h> 2 #define pi acos(-1) 3 using namespace std; 4 typedef long long LL; 5 typedef pair<int, int> P; 6 const int INF = 0x3f3f3f3f; 7 const LL ll_INF = 0x3f3f3f3f3f3f3f3f; 8 const int MAXN = 1e5 + 10; 9 const int mod = 1e9 + 7; 10 11 #define ls l,m,rt<<1 12 #define rs m+1,r,rt<<1|1 13 LL sum[MAXN<<2], add[MAXN<<2], mul[MAXN<<2]; 14 LL a[MAXN]; 15 LL n, m, p; 16 struct LazyTag 17 { 18 int mul, add, res; 19 }lz[MAXN<<2]; 20 21 void PushUp(int rt) { sum[rt] = ( sum[rt<<1]+sum[rt<<1|1] )%p; } 22 void PushDown(int rt, int ln, int rn) 23 { 24 sum[rt<<1] = ( sum[rt<<1]*mul[rt] + add[rt]*ln )%p; 25 sum[rt<<1|1] = ( sum[rt<<1|1]*mul[rt] + add[rt]*rn )%p; 26 27 mul[rt<<1] = ( mul[rt<<1]*mul[rt] )%p; 28 mul[rt<<1|1] = ( mul[rt<<1|1]*mul[rt] )%p; 29 30 add[rt<<1] = ( add[rt<<1]*mul[rt] + add[rt] )%p; 31 add[rt<<1|1] = ( add[rt<<1|1]*mul[rt] + add[rt] )%p; 32 33 mul[rt]=1; 34 add[rt]=0; 35 return ; 36 } 37 38 void Build(int l, int r, int rt) 39 { 40 mul[rt]=1; 41 add[rt]=0; 42 if(l==r){ 43 sum[rt]=a[l]; 44 return; 45 } 46 int mid = (l+r)>>1; 47 Build(l, mid, rt<<1); 48 Build(mid+1, r, rt<<1|1); 49 PushUp(rt); 50 } 51 52 //点的更新,假设A[L]+=C 53 void update_plus(int L, LL C, int l, int r, int rt) 54 { 55 if(l==r){ 56 sum[rt]+=C; 57 return; 58 } 59 int mid = (l+r)>>1; 60 PushDown(rt, mid-l+1, r-mid); 61 if(L <= mid) update_plus(L, C, l, mid, rt<<1); 62 else update_plus(L, C, mid+1, r, rt<<1|1); 63 PushUp(rt); 64 } 65 66 //区间更新,假设A[L,R]+=C 67 void update_plus(int L, int R, LL C, int l, int r, int rt) 68 { 69 if(L<=l && r<=R){ 70 sum[rt] = ( sum[rt] + C*(r-l+1) )%p; 71 add[rt] = ( add[rt] + C )%p ; 72 return ; 73 } 74 int mid = (l+r)>>1; 75 PushDown(rt, mid-l+1, r-mid); 76 if(L <= mid) update_plus(L, R, C, l, mid, rt<<1); 77 if(R > mid) update_plus(L, R, C, mid+1, r, rt<<1|1); 78 PushUp(rt); 79 } 80 81 void update_mutiple(int L, int R, LL k, int l, int r, int rt) 82 { 83 if(L<=l && r<=R){ 84 sum[rt] = ( sum[rt]*k )%p; 85 mul[rt] = ( mul[rt]*k )%p; 86 add[rt] = ( add[rt]*k )%p; 87 return ; 88 } 89 int mid = (l+r)>>1; 90 PushDown(rt, mid-l+1, r-mid); 91 if(L <= mid) update_mutiple(L, R, k, l, mid, rt<<1); 92 if(R > mid) update_mutiple(L, R, k, mid+1, r, rt<<1|1); 93 PushUp(rt); 94 } 95 96 //区间查询 97 LL Query(int L, int R, int l, int r, int rt) 98 { 99 if(L<=l && r<=R){ 100 return sum[rt]; 101 } 102 int mid = (l+r)>>1; 103 PushDown(rt, mid-l+1, r-mid); 104 LL ans=0; 105 if(L<=mid) ans = ( ans + Query(L, R, l, mid, rt<<1) )%p ; 106 if(R> mid) ans = ( ans + Query(L, R, mid+1, r, rt<<1|1) )%p; 107 return ans; 108 } 109 110 int main() 111 { 112 cin >> n >> m >> p; 113 for(int i=1; i<=n; i++) scanf("%lld", &a[i]); 114 Build(1, n, 1); 115 int flag, x, y; 116 LL k; 117 for(int i=1; i<=m; i++){ 118 scanf("%d%d%d", &flag, &x, &y); 119 if(flag==1){ 120 scanf("%lld", &k); 121 update_mutiple(x, y, k, 1, n, 1); 122 } 123 else if(flag==2){ 124 scanf("%lld", &k); 125 update_plus(x, y, k, 1, n, 1); 126 } 127 else if(flag==3){ 128 printf("%lld ", Query(x, y, 1, n, 1) ); 129 } 130 } 131 return 0; 132 }