[关闭]
@zhshh 2021-04-21T10:49:03.000000Z 字数 3635 阅读 987

线段树

@zhshh cpp OI 数据结构


模板

单标记(加、max、min)

回到顶部

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #define cnt tree[root]
  5. #define lr (root<<1)
  6. #define rr ((root<<1)|1)
  7. #define lt tree[lr]
  8. #define rt tree[rr]
  9. #define MX (100010)
  10. #define LL long long
  11. using namespace std;
  12. struct node{
  13. int left,right;
  14. LL add,val;
  15. node(){
  16. add=0;
  17. }
  18. }tree[MX<<2];
  19. LL a[MX];
  20. int n;
  21. void pushup(int root){
  22. cnt.val=lt.val+rt.val;//更新换成自己的操作
  23. }
  24. void pushdown(int root){
  25. if(cnt.add!=0){
  26. lt.val=lt.val+cnt.add*(lt.right-lt.left+1);
  27. lt.add=lt.add+cnt.add;
  28. rt.val=rt.val+cnt.add*(rt.right-rt.left+1);
  29. rt.add=rt.add+cnt.add;
  30. cnt.add=0;
  31. }
  32. }
  33. void add(int root,int left,int right,int c){
  34. if(left<=cnt.left && right>=cnt.right){
  35. cnt.add=cnt.add+c;
  36. cnt.val=(cnt.val+c*(cnt.right-cnt.left+1));
  37. return ;
  38. }
  39. pushdown(root);
  40. int mid=cnt.left+cnt.right>>1;
  41. if(left<=mid)add(lr,left,right,c);
  42. if(right>mid)add(rr,left,right,c);
  43. pushup(root);
  44. return ;
  45. }
  46. LL query(int root,int left,int right){
  47. if(left<=cnt.left && right>=cnt.right){
  48. return cnt.val;
  49. }
  50. pushdown(root);
  51. int mid=cnt.left+cnt.right>>1;
  52. LL ans=0;
  53. if(left<=mid)ans+=query(lr,left,right);
  54. if(right>mid)ans+=query(rr,left,right);
  55. return ans;
  56. }
  57. void build(int root,int left,int right){
  58. cnt.left=left;
  59. cnt.right=right;
  60. if(left==right){
  61. cnt.val=a[left];
  62. return ;
  63. }
  64. int mid=(cnt.left+cnt.right)>>1;
  65. build(lr,left,mid);
  66. build(rr,mid+1,right);
  67. pushup(root);
  68. return ;
  69. }
  70. int main(){
  71. int n,m;
  72. cin>>n>>m;
  73. for(int i=1;i<=n;i++){
  74. cin>>a[i];
  75. }
  76. build(1,1,n);
  77. int left,right,c;
  78. for(int i=1;i<=m;i++){
  79. cin>>c;
  80. if(c==1){
  81. cin>>left>>right>>c;
  82. add(1,left,right,c);
  83. }else{
  84. cin>>left>>right;
  85. cout<<query(1,left,right)<<endl;
  86. }
  87. }
  88. return 0;
  89. }

双标记

回到顶部

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #define cnt tree[root]
  5. #define lr (root<<1)
  6. #define rr ((root<<1)|1)
  7. #define lt tree[lr]
  8. #define rt tree[rr]
  9. #define ci const int
  10. #define MX (100010+10)
  11. #define LL long long
  12. using namespace std;
  13. struct node{
  14. int left,right;
  15. LL add,mul,val;
  16. node(){
  17. mul=1;
  18. add=0;
  19. }
  20. }tree[MX<<2];
  21. LL a[MX];
  22. int n;
  23. LL mod;
  24. void pushup(ci root){
  25. cnt.val=lt.val+rt.val;
  26. }
  27. void pushdown(ci root){
  28. if(cnt.mul!=1 || cnt.add!=0){
  29. lt.val=(lt.val*cnt.mul)%mod;
  30. lt.val=(lt.val+cnt.add*(lt.right-lt.left+1))%mod;
  31. lt.add=(lt.add*cnt.mul)%mod;
  32. lt.add=(lt.add+cnt.add)%mod;
  33. lt.mul=(lt.mul*cnt.mul)%mod;
  34. rt.val=(rt.val*cnt.mul)%mod;
  35. rt.val=(rt.val+cnt.add*(rt.right-rt.left+1))%mod;
  36. rt.add=(rt.add*cnt.mul)%mod;
  37. rt.add=(rt.add+cnt.add)%mod;
  38. rt.mul=(rt.mul*cnt.mul)%mod;
  39. cnt.mul=1;
  40. cnt.add=0;
  41. }
  42. }
  43. void mul(ci root,ci left,ci right,ci k){
  44. if(left<=cnt.left && right>=cnt.right){
  45. cnt.mul=(cnt.mul*k)%mod;
  46. cnt.add=(cnt.add*k)%mod;
  47. cnt.val=(cnt.val*k)%mod;
  48. return ;
  49. }
  50. pushdown(root);
  51. int mid=(cnt.left+cnt.right)>>1;
  52. if(left<=mid)mul(lr,left,right,k);
  53. if(right>mid)mul(rr,left,right,k);
  54. pushup(root);
  55. }
  56. void add(ci root,ci left,ci right,ci c){
  57. if(left<=cnt.left && right>=cnt.right){
  58. cnt.add=(cnt.add+c)%mod;
  59. cnt.val=(cnt.val+c*(cnt.right-cnt.left+1))%mod;
  60. return ;
  61. }
  62. pushdown(root);
  63. int mid=(cnt.left+cnt.right)>>1;
  64. if(left<=mid)add(lr,left,right,c);
  65. if(right>mid)add(rr,left,right,c);
  66. pushup(root);
  67. return ;
  68. }
  69. LL query(ci root,ci left,ci right){
  70. if(left<=cnt.left && right>=cnt.right){
  71. return cnt.val;
  72. }
  73. pushdown(root);
  74. int mid=(cnt.left+cnt.right)>>1;
  75. LL ans=0;
  76. if(left<=mid)ans=(ans+query(lr,left,right))%mod;
  77. if(right>mid)ans=(ans+query(rr,left,right))%mod;
  78. return ans;
  79. }
  80. void build(ci root,ci left,ci right){
  81. cnt.left=left;
  82. cnt.right=right;
  83. if(left==right){
  84. cnt.val=a[left];
  85. return ;
  86. }
  87. int mid=(cnt.left+cnt.right)>>1;
  88. build(lr,left,mid);
  89. build(rr,mid+1,right);
  90. pushup(root);
  91. return ;
  92. }
  93. void pr(){
  94. for(int i=1;i<=n;i++){
  95. printf("%3d%7d\n",i,query(1,i,i));
  96. }
  97. cout<<endl;
  98. }
  99. int main(){
  100. // freopen("in.txt","r",stdin);
  101. int m,t1,t2,t3;
  102. cin>>n>>m>>mod;
  103. for(int i=1;i<=n;i++){
  104. cin>>a[i];
  105. a[i]%=mod;
  106. }
  107. build(1,1,n);
  108. for(int i=1;i<=m;i++){
  109. cin>>t1;
  110. if(t1==1){
  111. cin>>t1>>t2>>t3;
  112. mul(1,t1,t2,t3);
  113. }else{
  114. if(t1==2){
  115. cin>>t1>>t2>>t3;
  116. add(1,t1,t2,t3);
  117. }else{
  118. cin>>t1>>t2;
  119. cout<<query(1,t1,t2)<<endl;
  120. }
  121. }
  122. }
  123. // pr();
  124. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注