[关闭]
@darkproject 2017-03-04T14:58:03.000000Z 字数 3401 阅读 803

线段树专题

集训队

A 敌兵布阵

标准的线段树,套个简单模板即可,涉及单点更新,区间查询部分

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <string>
  4. #include <cstring>
  5. const int maxn = 50000+5;
  6. using namespace std;
  7. struct {
  8. int left, right;
  9. int sum;
  10. }tree[maxn * 4];
  11. int n, a[maxn], p;
  12. string judstr;
  13. void push_up(int o)
  14. {
  15. tree[o].sum = tree[2 * o].sum + tree[2 * o + 1].sum;
  16. }
  17. void build(int l, int r, int o)
  18. {
  19. tree[o].left = l, tree[o].right = r, tree[o].sum = 0;
  20. if (l == r) tree[o].sum = a[l];
  21. else
  22. {
  23. int mid = (r + l) / 2;
  24. build(l, mid, 2 * o);
  25. build(mid + 1, r, 2 * o + 1);
  26. push_up(o);
  27. }
  28. }
  29. int query(int ql, int qr, int o)
  30. {
  31. int l = tree[o].left, r = tree[o].right;
  32. if (ql <= l&&r <= qr) return tree[o].sum;
  33. else {
  34. int ans = 0;
  35. int mid=(l + r) / 2;
  36. if (ql <= mid) ans += query(ql, qr, 2 * o);
  37. if (qr>mid) ans += query(ql, qr, 2 * o + 1);
  38. return ans;
  39. }
  40. }
  41. void update(int pos, int o, int x)
  42. {
  43. int l = tree[o].left,r = tree[o].right;
  44. if (l == r&&tree[o].left == pos)
  45. {
  46. tree[o].sum += x;
  47. return;
  48. }
  49. else {
  50. int mid = (l + r) / 2;
  51. if (mid<pos)
  52. update(pos, 2 * o + 1, x);
  53. else
  54. update(pos, 2 * o, x);
  55. push_up(o);
  56. }
  57. }
  58. int main()
  59. {
  60. int t;
  61. cin >> t;
  62. while (t--)
  63. {
  64. cin >> n;
  65. memset(a, 0, sizeof(a));
  66. for (int i = 1; i <= n; ++i)
  67. scanf("%d", &a[i]);
  68. build(1, n, 1);
  69. printf("Case %d:\n", ++p);
  70. while (1)
  71. {
  72. int i, j;
  73. cin >> judstr;
  74. if (judstr == "End") break;
  75. scanf("%d%d", &i, &j);
  76. if (judstr == "Query")
  77. printf("%d\n", query(i, j, 1));
  78. else if (judstr == "Add")
  79. {
  80. update(i, 1, j);
  81. }
  82. else
  83. update(i, 1, -j);
  84. }
  85. }
  86. return 0;
  87. }

B - Color the ball

线段树区间更新与查询,初始化化序列为0,更新+1

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<algorithm>
  4. using namespace std;
  5. int a[1000000], n;
  6. struct
  7. {
  8. int l, r;
  9. int n;
  10. }tree[1000000];
  11. void build(int l, int r, int o)
  12. {
  13. tree[o].l = l;
  14. tree[o].r = r;
  15. tree[o].n = 0;
  16. if (l != r)
  17. {
  18. int mid = (l + r) >> 1;
  19. build(l, mid, 2 * o);
  20. build(mid + 1, r, 2 * o + 1);
  21. }
  22. }
  23. void query(int o)
  24. {
  25. int i;
  26. for (i = tree[o].l; i <= tree[o].r; i++)
  27. a[i] += tree[o].n;
  28. if (tree[o].l == tree[o].r)
  29. return;
  30. query(2 * o);
  31. query(2 * o + 1);
  32. }
  33. void update(int x, int y, int o)
  34. {
  35. int l = tree[o].l, r = tree[o].r;
  36. if (l == x&&r == y)
  37. tree[o].n++;
  38. else
  39. {
  40. int mid = (l + r)/2;
  41. if (y <= mid) update(x, y, 2 * o);
  42. else if (x > mid) update(x, y, 2 * o + 1);
  43. else
  44. {
  45. update(x, mid, 2 * o);
  46. update(mid+1, y, 2 * o + 1);
  47. }
  48. }
  49. }
  50. int main()
  51. {
  52. int i, j;
  53. while (~scanf("%d", &n),n)
  54. {
  55. memset(a, 0, sizeof(a));
  56. build(1, n, 1);
  57. for(int p=1;p<=n;++p)
  58. {
  59. scanf("%d%d", &i, &j);
  60. update(i,j,1);
  61. }
  62. query(1);
  63. printf("%d", a[1]);
  64. for (int k = 2; k <= n; ++k)
  65. printf(" %d", a[k]);
  66. printf("\n");
  67. }
  68. return 0;
  69. }

E - A Simple Problem with Integers (poj3468)

区间统一更新加c,区间查询

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <algorithm>
  5. const int maxn = 1e5 + 5;
  6. int n, q;
  7. int a[maxn];
  8. using namespace std;
  9. typedef long long SgTreeDataType;
  10. struct
  11. {
  12. int L, R;
  13. SgTreeDataType sum, lazy;
  14. void updata(SgTreeDataType v)
  15. {
  16. sum += (R - L + 1)*v;
  17. lazy += v;
  18. }
  19. }tree[maxn*4];
  20. void push_down(int o)
  21. {
  22. SgTreeDataType lazyval = tree[o].lazy;
  23. tree[2 * o].updata(lazyval); tree[2 * o + 1].updata(lazyval);
  24. tree[o].lazy = 0;
  25. }
  26. void push_up(int o)
  27. {
  28. tree[o].sum = tree[2 * o].sum + tree[2 * o + 1].sum;
  29. }
  30. void build_tree(int L, int R, int o)
  31. {
  32. tree[o].L = L, tree[o].R = R, tree[o].sum = tree[o].lazy = 0;
  33. if (R == L)
  34. tree[o].sum = a[L];
  35. else
  36. {
  37. int mid = (L + R) >> 1;
  38. build_tree(L, mid, o * 2);
  39. build_tree(mid + 1, R, o * 2 + 1);
  40. push_up(o);
  41. }
  42. }
  43. void updata(int QL, int QR, SgTreeDataType v, int o)
  44. {
  45. int L = tree[o].L, R = tree[o].R;
  46. if (QL <= L && R <= QR) tree[o].updata(v);
  47. else
  48. {
  49. push_down(o);
  50. int mid = (L + R) >> 1;
  51. if (QL <= mid) updata(QL, QR, v, o * 2);
  52. if (QR > mid) updata(QL, QR, v, o * 2 + 1);
  53. push_up(o);
  54. }
  55. }
  56. SgTreeDataType query(int QL, int QR, int o)
  57. {
  58. int L = tree[o].L, R = tree[o].R;
  59. if (QL <= L && R <= QR) return tree[o].sum;
  60. else
  61. {
  62. push_down(o);
  63. int mid = (L + R) >> 1;
  64. SgTreeDataType res = 0;
  65. if (QL <= mid) res += query(QL, QR, 2 * o);
  66. if (QR > mid) res += query(QL, QR, 2 * o + 1);
  67. push_up(o);
  68. return res;
  69. }
  70. }
  71. int main()
  72. {
  73. int x, y, c;
  74. char ch;
  75. scanf("%d%d", &n, &q);
  76. for (int i = 1; i <= n; ++i)
  77. scanf("%d", &a[i]);
  78. build_tree(1, n, 1);
  79. while (q--)
  80. {
  81. scanf(" %c", &ch);
  82. if (ch == 'Q') {
  83. scanf("%d%d", &x, &y);
  84. printf("%lld\n", query(x, y, 1));
  85. }
  86. else
  87. {
  88. scanf("%d%d%d", &x, &y,&c);
  89. updata(x, y, c, 1);
  90. }
  91. }
  92. return 0;
  93. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注