POJ 3468 A Simple Problem with Integers (线段树---区间更新)

朴灿烈づ我的快乐病毒、 2024-02-17 21:10 132阅读 0赞

A Simple Problem with Integers

















     
     
 

Description

You have N integers, A1, A2, … , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, … , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
“C a b c“ means adding c to each of Aa, Aa+1, … , Ab. -10000 ≤ c ≤ 10000.
“Q a b“ means querying the sum of Aa, Aa+1, … , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

  1. 10 5
  2. 1 2 3 4 5 6 7 8 9 10
  3. Q 4 4
  4. Q 1 10
  5. Q 2 4
  6. C 3 6 3
  7. Q 2 4

Sample Output

  1. 4
  2. 55
  3. 9
  4. 15

分析:线段树之区间更新,根据区间更新模板就可以很容易的写出来

AC代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. using namespace std;
  4. typedef long long LL;
  5. const int maxn=1e5+10;
  6. LL sum[maxn<<2];
  7. LL cnt[maxn<<2]; //延迟标记
  8. int N,Q;
  9. void build(int l,int r,int rt){
  10. cnt[rt]=0;
  11. if(l==r){
  12. scanf("%lld",&sum[rt]); //输入时注意lld,没注意到WA了一次
  13. return ;
  14. }
  15. int m=(l+r)>>1;
  16. build(l,m,rt<<1);
  17. build(m+1,r,rt<<1|1);
  18. sum[rt]=sum[rt<<1]+sum[rt<<1|1];
  19. }
  20. void Down(int rt,int len){
  21. if(cnt[rt]){
  22. cnt[rt<<1]+=cnt[rt];
  23. cnt[rt<<1|1]+=cnt[rt];
  24. sum[rt<<1]+=cnt[rt]*(len-(len>>1));
  25. sum[rt<<1|1]+=cnt[rt]*(len>>1);
  26. cnt[rt]=0;
  27. }
  28. }
  29. LL Query(int a,int b,int l,int r,int rt){
  30. if(a<=l && b>=r){
  31. return sum[rt];
  32. }
  33. Down(rt,r-l+1);
  34. int m=(l+r)>>1;
  35. LL ans=0;
  36. if(a<=m)
  37. ans+=Query(a,b,l,m,rt<<1);
  38. if(b>m)
  39. ans+=Query(a,b,m+1,r,rt<<1|1);
  40. sum[rt]=sum[rt<<1]+sum[rt<<1|1];
  41. return ans;
  42. }
  43. void Update(int a,int b,int c,int l,int r,int rt){
  44. if(a<=l && b>=r){
  45. cnt[rt]+=c;
  46. sum[rt]+=(LL)(r-l+1)*c;
  47. return ;
  48. }
  49. Down(rt,r-l+1);
  50. int m=(r+l)>>1;
  51. if(a<=m)
  52. Update(a,b,c,l,m,rt<<1);
  53. if(b>m)
  54. Update(a,b,c,m+1,r,rt<<1|1);
  55. sum[rt]=sum[rt<<1]+sum[rt<<1|1];
  56. }
  57. int main(){
  58. while(scanf("%d%d",&N,&Q)==2){
  59. build(1,N,1);
  60. for(int i=0;i<Q;i++){
  61. char ch;
  62. int a,b,c;
  63. getchar();
  64. scanf("%c",&ch);
  65. if(ch=='Q'){
  66. scanf("%d%d",&a,&b);
  67. LL ans=Query(a,b,1,N,1);
  68. printf("%lld\n",ans);
  69. }
  70. else {
  71. scanf("%d%d%d",&a,&b,&c);
  72. Update(a,b,c,1,N,1);
  73. }
  74. }
  75. }
  76. return 0;
  77. }

发表评论

表情:
评论列表 (有 0 条评论,132人围观)

还没有评论,来说两句吧...

相关阅读