首页 > 代码库 > poj 3468

poj 3468

  1. #include <vector>
  2. #include <queue>
  3. #include <stack>
  4. #include <set>
  5. #include <map>
  6. #include <algorithm>
  7. #include <iostream>
  8. #include <cstdio>
  9. #include <cstring>
  10. #define MAXN 100005
  11. #define LC(x) ((x) << 1)
  12. #define RC(x) ((x) << 1 | 1)
  13. #define Mid(x,y) (((x) + (y)) >> 1)
  14. #define Min(a,b) ((a) < (b) ? (a) : (b))
  15. #define Max(a,b) ((a) > (b) ? (a) : (b))
  16. long long int sum[MAXN<<2],dlt[MAXN<<2];
  17. int lft[MAXN<<2],rht[MAXN<<2];
  18. long long int init_v[MAXN+10];
  19. using namespace std;
  20. void pushdown(int rt){
  21. if(dlt[rt]){
  22. dlt[LC(rt)]+=dlt[rt];
  23. sum[LC(rt)]+=(rht[LC(rt)]-lft[LC(rt)]+1)*dlt[rt]; //width*height
  24. dlt[RC(rt)]+=dlt[rt];
  25. sum[RC(rt)]+=(rht[RC(rt)]-lft[RC(rt)]+1)*dlt[rt];
  26. dlt[rt]=0;
  27. }
  28. }
  29. void pushup(int rt){
  30. sum[rt] = sum[LC(rt)] + sum[RC(rt)];
  31. }
  32. void update(int rt,int start,int end,long long int delta)
  33. {
  34. if(start<=lft[rt]&&end>=rht[rt]){
  35. dlt[rt]+=delta;
  36. sum[rt] += (rht[rt]-lft[rt]+1)*delta;
  37. return;
  38. }
  39. pushdown(rt);// 顺便将之前未更新到儿子的信息pushdown
  40. if(start<=rht[LC(rt)]) update(LC(rt),start,end,delta); //要更新的区间和左儿子有交集(区间左界<=左儿子右界)
  41. if(end>=lft[RC(rt)]) update(RC(rt),start,end,delta); //要更新的区间和右儿子有交集
  42. pushup(rt);//返回时候更新当前节点
  43. }
  44. void build(int rt,int l,int r)
  45. {
  46. lft[rt]=l;
  47. rht[rt]=r;
  48. dlt[rt]=0;
  49. if(l==r){
  50. sum[rt]=init_v[l];
  51. return;
  52. }
  53. else{
  54. build(LC(rt),l,Mid(l,r));
  55. build(RC(rt),Mid(l,r)+1,r);
  56. pushup(rt);
  57. return;
  58. }
  59. }
  60. long long int query(int rt,int start,int end)
  61. {
  62. if(start>rht[rt]||end<lft[rt]) return 0;
  63. //如果当前节点在查询的范围内就直接返回
  64. if(start<=lft[rt]&&end>=rht[rt])
  65. return sum[rt];
  66. pushdown(rt);//顺便更新之前的标记
  67. // if(start>=lft[RC(rt)]) //区间只和右儿子有交集 区间左界大于等于右儿子左界
  68. // return query(RC(rt),start,end);
  69. // else
  70. // if(end<=rht[LC(rt)]) //区间只和左儿子有集交
  71. // return query(LC(rt),start,end);
  72. // else //左右儿子都有交集
  73. return query(LC(rt),start,end) + query(RC(rt),start,end);
  74. }
  75. int main(int argc, char *argv[])
  76. {
  77. int n,q,i,j,start,end;
  78. long long int delta;
  79. char ch[2];
  80. while(scanf("%d%d",&n,&q)!=EOF)
  81. {
  82. for(i=1;i<=n;i++) scanf("%lld",init_v+i);
  83. build(1,1,n);
  84. while(q--)
  85. {
  86. scanf("%s",ch);
  87. if(ch[0]==‘C‘)
  88. {
  89. scanf("%d%d%lld",&start,&end,&delta);
  90. update(1,start,end,delta);
  91. }
  92. else
  93. {
  94. scanf("%d%d",&start,&end);
  95. printf("%lld\n",query(1,start,end));
  96. }
  97. }
  98. return 0;
  99. }
  100. }



来自为知笔记(Wiz)


附件列表

     

    poj 3468