记录编号 535093 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 数列操作C 最终得分 100
用户昵称 Gravatar数声风笛ovo 是否通过 通过
代码语言 C++ 运行时间 1.566 s
提交时间 2019-07-04 08:47:32 内存使用 21.67 MiB
显示代码纯文本
  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. class qwq{//普通的建树操作
  5. public:
  6. int l,r,lc,rc;//左端点,右端点,左儿子节点的编号,右儿子节点的编号
  7. ll sum;
  8. ll lazy;//懒标记,本题难点
  9. }tree[233333];
  10. int QAQ[233333]={0};//卖个萌嘻嘻
  11. int num=1; //定义变量以存储L值与R值
  12. void build(int l,int r){//存树操作,因为存在懒标记所以方式存在差异
  13. int mid=(l+r)/2;
  14. int root=num;
  15. tree[root].l=l;tree[root].r=r;
  16. tree[root].lazy=0;//懒标记初始化
  17. if(l<r){//左右端点不重合
  18. tree[root].lc=++num;
  19. build(l,mid);//存左孩子
  20. tree[root].rc=++num;
  21. build(mid+1,r);//存右孩子
  22. tree[root].sum=tree[tree[root].lc].sum+tree[tree[root].rc].sum;
  23. }
  24. else{//左右端点重合
  25. tree[root].lc=0;tree[root].rc=0;//节点两端点重合,即没有孩子
  26. tree[root].sum=QAQ[l];
  27. }
  28. return;
  29. }
  30. void add(int root,int gl,int gr,ll plus,ll lazytag){
  31. //区间加值,本函数调用变量从左至右分别为当前节点编号,加值操作范围左、右端点,所加的值与懒标记值
  32. if(root==-1) return;//意义不明的判错程序
  33. if(gl>tree[root].r||gr<tree[root].l){//所访问节点线段不在加值范围内
  34. tree[root].sum+=lazytag*(tree[root].r-tree[root].l+1);
  35. tree[root].lazy+=lazytag;
  36. return;
  37. }
  38. if(gl<=tree[root].l&&gr>=tree[root].r){//所访问节点线段在加值范围内
  39. tree[root].lazy+=(plus+lazytag);
  40. tree[root].sum+=(plus+lazytag)*(tree[root].r-tree[root].l+1);
  41. return;
  42. }
  43. else{//所访问节点线段部分在加值范围内
  44. add(tree[root].lc,gl,gr,plus,lazytag+tree[root].lazy);//访问其左孩子
  45. add(tree[root].rc,gl,gr,plus,lazytag+tree[root].lazy);//访问其右孩子
  46. tree[root].lazy=0;//懒标记归零
  47. if(tree[root].lc!=-1){//重置被van坏掉的线段树(???)
  48. tree[root].sum=tree[tree[root].lc].sum+tree[tree[root].rc].sum;
  49. }
  50. }
  51. return;
  52. }
  53. ll sum(int root,int gl,int gr,ll lazytag){
  54. //区间查询,本函数调用变量从左至右分别为当前节点编号,查值操作范围左、右端点与懒标记值
  55. if(root==-1) return 0;//意义不明的判错程序
  56. if(gl>tree[root].r||gr<tree[root].l) return 0;//所访问节点线段不在查值范围内
  57. if(gl<=tree[root].l&&gr>=tree[root].r){//所访问节点线段在查值范围内
  58. return tree[root].sum+lazytag*(tree[root].r-tree[root].l+1);
  59. }
  60. return sum(tree[root].lc,gl,gr,lazytag+tree[root].lazy)+sum(tree[root].rc,gl,gr,lazytag+tree[root].lazy);//所访问节点线段包含加值范围
  61. }
  62. int cxw(){
  63. int a,b,c,n,m;char ovo[5];
  64. freopen("shuliec.in","r",stdin);
  65. freopen("shuliec.out","w",stdout);
  66. scanf("%d",&n);
  67. for(int i=1;i<=n;i++){
  68. scanf("%d",&QAQ[i]);
  69. }
  70. build(1,n);//存树操作
  71. scanf("%d",&m);
  72. for(int i=1;i<=m;i++){
  73. scanf("%s",&ovo);
  74. if(ovo[0]=='A'){//加值操作
  75. scanf("%d%d%d",&a,&b,&c);
  76. add(1,a,b,c,0);
  77. }
  78. else{//查值操作
  79. scanf("%d%d",&a,&b);
  80. printf("%lld\n",sum(1,a,b,0));
  81. }
  82. }
  83. return 0;
  84. }
  85. int wjb=cxw();
  86. int main(void){;}
  87.