POJ 3468 A Simple Problem with Integers ——————线段树,维护区间

╰半夏微凉° 2022-05-15 00:14 261阅读 0赞

A Simple Problem with Integers

Language:Default

A Simple Problem with Integers

















Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 141040 Accepted: 43753
Case Time Limit: 2000MS

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

Hint

The sums may exceed the range of 32-bit integers.

Source

POJ Monthly—2007.11.25, Yang Yi


线段树,区间查询及更改区间的值(给一个区间所有的数都加上一个值)

  1. /*
  2. * 白书的板子
  3. * 认真思考,仔细理解
  4. */
  5. #include<cstdio>
  6. #include<iostream>
  7. #include<algorithm>
  8. #include<cstring>
  9. #include<string>
  10. using namespace std;
  11. typedef long long ll;
  12. const int MAX_N=1e5+7;
  13. const int DAT_SIZE=1<<20;
  14. int N,Q;
  15. int A[MAX_N];
  16. char T[MAX_N];
  17. int L[MAX_N],R[MAX_N],X[MAX_N];
  18. // 线段树
  19. ll data[DAT_SIZE],datb[DAT_SIZE];
  20. /*
  21. * 对区间[a, b)同时加x
  22. * k 是节点的编号,对应的是区间[l, r)
  23. */
  24. void add(int a, int b, int x, int k,int l,int r)
  25. {
  26. if(a <= l && r <= b) data[k] += x;
  27. else if(l < b && a < r)
  28. {
  29. datb[k] += (min(b,r) - max(a,l))*x;
  30. add(a, b, x, k * 2 + 1, l, (l + r) / 2);
  31. add(a, b, x, k * 2 + 2, (l + r) / 2, r);
  32. }
  33. }
  34. /*
  35. * 计算[a, b)的和
  36. * k 是节点的编号,对应的是区间[l, r)
  37. */
  38. ll sum(int a, int b, int k, int l, int r)
  39. {
  40. if(b <= l || r <= a) return 0;
  41. else if(a <= l && r <= b) return data[k] * (r - l) + datb[k];
  42. else
  43. {
  44. ll res = (min(b, r) - max(a, l)) * data[k];
  45. res += sum(a, b, k * 2 + 1, l, (l + r) / 2);
  46. res += sum(a, b, k * 2 + 2, (l + r) / 2, r);
  47. return res;
  48. }
  49. }
  50. int main()
  51. {
  52. ios::sync_with_stdio(0);
  53. cin>>N>>Q;
  54. for(int i=0;i<N;i++)
  55. {
  56. cin>>A[i];
  57. add(i,i+1,A[i],0,0,N);
  58. }
  59. for(int i=0;i<Q;i++)
  60. {
  61. cin>>T[i];
  62. if(T[i]=='C')
  63. {
  64. cin>>L[i]>>R[i]>>X[i];
  65. add(L[i]-1, R[i], X[i], 0, 0, N);
  66. // cout<<T[i]<<L[i]<<R[i]<<X[i]<<endl;
  67. }
  68. else
  69. {
  70. cin>>L[i]>>R[i];
  71. cout<<sum(L[i]-1, R[i], 0, 0, N)<<endl;
  72. // cout<<T[i]<<L[i]<<R[i]<<endl;
  73. }
  74. }
  75. return 0;
  76. }

感觉跟没写一样呀,别人都是用的lazy

  1. /**
  2. *        ┏┓   ┏┓+ +
  3. *       ┏┛┻━━━┛┻┓ + +
  4. *       ┃       ┃
  5. *       ┃   ━   ┃ ++ + + +
  6. *       ████━████ ┃+
  7. *       ┃       ┃ +
  8. *       ┃   ┻   ┃
  9. *       ┃       ┃ + +
  10. *       ┗━┓   ┏━┛
  11. *         ┃   ┃
  12. *         ┃   ┃ + + + +
  13. *         ┃   ┃    Code is far away from bug with the animal protecting
  14. *         ┃   ┃ +     神兽保佑,代码无bug
  15. *         ┃   ┃
  16. *         ┃   ┃  +
  17. *         ┃    ┗━━━┓ + +
  18. *         ┃        ┣┓
  19. *         ┃        ┏┛
  20. *         ┗┓┓┏━┳┓┏┛ + + + +
  21. *          ┃┫┫ ┃┫┫
  22. *          ┗┻┛ ┗┻┛+ + + +
  23. */
  24. /*--------- Hongjie ----------*/
  25. // #include<bits/stdc++.h>
  26. #include<map>
  27. #include<set>
  28. #include<queue>
  29. #include<stack>
  30. #include<deque>
  31. #include<cmath>
  32. #include<cstdio>
  33. #include<bitset>
  34. #include<string>
  35. #include<vector>
  36. #include<cstring>
  37. #include<iostream>
  38. #include<algorithm>
  39. using namespace std;
  40. typedef long long ll;
  41. typedef pair<int ,int> P;
  42. const int INF = 0x3f3f3f3f;
  43. const int MAXN = 1e6+7;
  44. ll data[MAXN],datb[MAXN];
  45. int n,q;
  46. void init(int _n) {
  47. //建造一个完全二叉树
  48. n = 1;
  49. while(n<_n) n<<=1;
  50. memset(data,0,sizeof(ll)*(n*4));
  51. memset(datb,0,sizeof(ll)*(n*4));
  52. }
  53. void update(int k,int a) {
  54. k += n-1;
  55. datb[k] = a;
  56. while(k>0) {
  57. k = (k-1)/2;
  58. datb[k] = datb[k*2+1]+datb[k*2+2];
  59. }
  60. }
  61. void add(int a,int b,int x,int k,int l,int r){
  62. if(a<=l && r<=b)//[l,r) in [a,b)
  63. data[k] += x;
  64. else if(l<b && a<r) {
  65. // [l,r) 相交 [a,b)
  66. datb[k] += x*(min(b,r)-max(a,l));
  67. add(a,b,x,k*2+1,l,(l+r)/2);
  68. add(a,b,x,k*2+2,(l+r)/2,r);
  69. }
  70. }
  71. ll sum(int a,int b,int k,int l,int r) {
  72. if(b<=l || r<=a) return 0;//[l,r) not in [a,b)
  73. else if(a<=l && r<=b) return data[k]*(r-l)+datb[k];//[l,r) in [a,b)
  74. else {
  75. ll res = data[k]*(min(b,r) - max(a,l));
  76. res += sum(a,b,k*2+1,l,(l+r)/2);
  77. res += sum(a,b,k*2+2,(l+r)/2,r);
  78. return res;
  79. }
  80. }
  81. int main(){
  82. // freopen("../in.txt","r",stdin);
  83. // freopen("../out.txt","w",stdout);
  84. ios::sync_with_stdio(0);
  85. cin.tie(0);
  86. while(cin>>n>>q) {
  87. int n_ = n;
  88. init(n);
  89. for(int i=0;i<n_;++i) {
  90. int x;
  91. cin>>x;
  92. update(i,x);
  93. }
  94. string ch;
  95. int a,b,c;
  96. for(int i=0;i<q;++i) {
  97. cin>>ch;
  98. if(ch[0]=='C') {
  99. cin>>a>>b>>c;
  100. add(a-1,b,c,0,0,n);
  101. }
  102. else{
  103. cin>>a>>b;
  104. cout<<sum(a-1,b,0,0,n)<<endl;
  105. }
  106. }
  107. }
  108. return 0;
  109. }

发表评论

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

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

相关阅读