题目大意:
维护一个数列,支持区间乘,区间加,求区间和.
线段树题,对于乘和加操作我们可以维护一个标记.对于乘用乘法分配律分解.
代码如下:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int N = 100010; 7 int inline getint() 8 { 9 int num = 0;char ch = getchar();for(;ch < ‘0‘ || ch > ‘9‘;ch = getchar()); 10 for(;ch >= ‘0‘ && ch <= ‘9‘;ch = getchar()) num = (num << 3) + (num << 1) + ch - ‘0‘; 11 return num; 12 } 13 void putint(int x){if(x > 9)putint(x / 10);putchar(x % 10 + ‘0‘);} 14 int sum[1 + (N << 2)],col1[1 + (N << 2)],col2[1 + (N << 2)],n,m,p; 15 void pushup(int &x){sum[x] = (sum[x << 1] + sum[x << 1 | 1]) % p;} 16 void build(int l,int r,int x) 17 { 18 col1[x] = 1; 19 if(l == r){sum[x] = getint() % p;return;} 20 int mid = l + r >> 1; 21 if(l <= mid) build(l,mid,x << 1); 22 if(r > mid) build(mid + 1,r,x << 1 | 1); 23 pushup(x); 24 } 25 void pushdown(int &x,int &l,int &r) 26 { 27 if(col1[x] != 1) 28 { 29 col1[x << 1] = (long long)col1[x << 1] * col1[x] % p; 30 col2[x << 1] = (long long)col2[x << 1] * col1[x] % p; 31 sum[x << 1] = (long long)sum[x << 1] * col1[x] % p; 32 col1[x << 1 | 1] = (long long)col1[x << 1 | 1] * col1[x] % p; 33 col2[x << 1 | 1] = (long long)col2[x << 1 | 1] * col1[x] % p; 34 sum[x << 1 | 1] = (long long)sum[x << 1 | 1] * col1[x] % p; 35 col1[x] = 1; 36 } 37 if(col2[x]) 38 { 39 col2[x << 1] = (col2[x << 1] + col2[x]) % p; 40 sum[x << 1] = ((long long)col2[x] * ((l + r >> 1) - l + 1) % p + sum[x << 1]) % p; 41 col2[x << 1 | 1] = (col2[x << 1 | 1] + col2[x]) % p; 42 sum[x << 1 | 1] = ((long long)col2[x] * (r - (l + r >> 1)) % p + sum[x << 1 | 1]) % p; 43 col2[x] = 0; 44 } 45 } 46 void add(int l,int r,int root,int L,int R,int x) 47 { 48 if(l >= L && r <= R) 49 { 50 col2[root] = (col2[root] + x) % p; 51 sum[root] = ((long long)(r - l + 1) * x % p + sum[root]) % p; 52 return; 53 } 54 pushdown(root,l,r); 55 int mid = l + r >> 1; 56 if(L <= mid) add(l,mid,root << 1,L,R,x); 57 if(R > mid) add(mid + 1,r,root << 1 | 1,L,R,x); 58 pushup(root); 59 } 60 void mul(int l,int r,int root,int L,int R,int x) 61 { 62 if(l >= L && r <= R) 63 { 64 col1[root] = (long long)col1[root] * x % p; 65 col2[root] = (long long)col2[root] * x % p; 66 sum[root] = (long long)sum[root] * x % p; 67 return; 68 } 69 pushdown(root,l,r); 70 int mid = l + r >> 1; 71 if(L <= mid) mul(l,mid,root << 1,L,R,x); 72 if(R > mid) mul(mid + 1,r,root << 1 | 1,L,R,x); 73 pushup(root); 74 } 75 int query(int l,int r,int root,int L,int R) 76 { 77 if(l >= L && r <= R)return sum[root]; 78 pushdown(root,l,r); 79 int mid = l + r >> 1,ret = 0; 80 if(L <= mid)ret = query(l,mid,root << 1,L,R); 81 if(R > mid)ret = (ret + query(mid + 1,r,root << 1 | 1,L,R)) % p; 82 return ret; 83 } 84 int main() 85 { 86 n = getint();p = getint();build(1,n,1); 87 m = getint(); 88 for(int i = 1;i <= m;i++) 89 { 90 int opt = getint(),t,g,c; 91 switch(opt) 92 { 93 case 1: 94 t = getint();g = getint();c = getint() % p; 95 mul(1,n,1,t,g,c);break; 96 case 2: 97 t = getint();g = getint();c = getint() % p; 98 add(1,n,1,t,g,c);break; 99 case 3: 100 t = getint();g = getint(); 101 putint(query(1,n,1,t,g));putchar(‘\n‘); 102 break; 103 } 104 } 105 return 0; 106 }
时间: 2024-09-30 07:27:28