模板:线段树(2)——加法,乘法,求和
https://www.luogu.org/problemnew/show/P3373
区间加法乘法修改,区间查询
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int p; 5 long long a[100005]; 6 struct node{ 7 long long v, mul, add; 8 }st[500005]; 9 void bt(int root, int l, int r){ 10 //初始化lazytag 11 st[root].mul=1; 12 st[root].add=0; 13 if(l==r){ 14 st[root].v=a[l]; 15 } 16 else{ 17 int m=(l+r)/2; 18 bt(root*2, l, m); 19 bt(root*2+1, m+1, r); 20 st[root].v=st[root*2].v+st[root*2+1].v; 21 } 22 st[root].v%=p; 23 return ; 24 } 25 void pushdown(int root, int l, int r){ 26 int m=(l+r)/2; 27 //儿子的值=此刻儿子的值*爸爸的乘法lazytag+儿子的区间长度*爸爸的加法lazytag 28 st[root*2].v=(st[root*2].v*st[root].mul+st[root].add*(m-l+1))%p; 29 st[root*2+1].v=(st[root*2+1].v*st[root].mul+st[root].add*(r-m))%p; 30 st[root*2].mul=(st[root*2].mul*st[root].mul)%p; 31 st[root*2+1].mul=(st[root*2+1].mul*st[root].mul)%p; 32 st[root*2].add=(st[root*2].add*st[root].mul+st[root].add)%p; 33 st[root*2+1].add=(st[root*2+1].add*st[root].mul+st[root].add)%p; 34 //把父节点的值初始化 35 st[root].mul=1; 36 st[root].add=0; 37 return ; 38 } 39 //乘法,stdl此刻, l给出的 40 void ud1(int root, int stdl, int stdr, int l, int r, long long k){ 41 if(r<stdl || stdr<l){ 42 return ; 43 } 44 if(l<=stdl && stdr<=r){ 45 st[root].v=(st[root].v*k)%p; 46 st[root].mul=(st[root].mul*k)%p; 47 st[root].add=(st[root].add*k)%p; 48 return ; 49 } 50 pushdown(root, stdl, stdr); 51 int m=(stdl+stdr)/2; 52 ud1(root*2, stdl, m, l, r, k); 53 ud1(root*2+1, m+1, stdr, l, r, k); 54 st[root].v=(st[root*2].v+st[root*2+1].v)%p; 55 return ; 56 } 57 //加法 58 void ud2(int root, int stdl, int stdr, int l, int r, long long k){ 59 if(r<stdl || stdr<l){ 60 return ; 61 } 62 if(l<=stdl && stdr<=r){ 63 st[root].add=(st[root].add+k)%p; 64 st[root].v=(st[root].v+k*(stdr-stdl+1))%p; 65 return ; 66 } 67 pushdown(root, stdl, stdr); 68 int m=(stdl+stdr)/2; 69 ud2(root*2, stdl, m, l, r, k); 70 ud2(root*2+1, m+1, stdr, l, r, k); 71 st[root].v=(st[root*2].v+st[root*2+1].v)%p; 72 return ; 73 } 74 long long query(int root, int stdl, int stdr, int l, int r){ 75 if(r<stdl || stdr<l){ 76 return 0; 77 } 78 if(l<=stdl && stdr<=r){ 79 return st[root].v; 80 } 81 pushdown(root, stdl, stdr); 82 int m=(stdl+stdr)/2; 83 return (query(root*2, stdl, m, l, r)+query(root*2+1, m+1, stdr, l, r))%p; 84 } 85 int main(){ 86 int n, m; 87 scanf("%d%d%d", &n, &m, &p); 88 for(int i=1; i<=n; i++){ 89 scanf("%lld", &a[i]); 90 } 91 bt(1, 1, n); 92 for(int i=1; i<=m; i++){ 93 int aha; 94 scanf("%d", &aha); 95 int x, y; 96 long long k; 97 if(aha==1){ 98 scanf("%d%d%lld", &x, &y, &k); 99 ud1(1, 1, n, x, y, k); 100 } 101 else if(aha==2){ 102 scanf("%d%d%lld", &x, &y, &k); 103 ud2(1, 1, n, x, y, k); 104 } 105 else{ 106 scanf("%d%d", &x, &y); 107 printf("%lld\n", query(1, 1, n, x, y)); 108 } 109 } 110 return 0; 111 }
"Hello World!"