记录编号 599113 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [SYOI 2018] 简单的线段树 最终得分 100
用户昵称 GravatarLikableP 是否通过 通过
代码语言 C++ 运行时间 13.559 s
提交时间 2025-02-28 19:09:15 内存使用 5.97 MiB
显示代码纯文本
  1. #pragma GCC optimize(2)
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <fstream>
  5. #define ls(root) root << 1
  6. #define rs(root) root << 1 | 1
  7. #define Merge(root) tree[root] = (tree[ls(root)] + tree[rs(root)]) % p;
  8. using namespace std;
  9. typedef long long ll;
  10.  
  11. const int MAXN = 1e5;
  12.  
  13. int n, m, p;
  14. ll a[MAXN + 10];
  15.  
  16. ll tree[(MAXN << 2) + 10], lazya[(MAXN << 2) + 10], lazym[(MAXN << 2) + 10];
  17. void Build(int root, int lt, int rt) {
  18. lazym[root] = 1;
  19. if (lt == rt) return ;
  20. int mid = lt + ((rt - lt) >> 1);
  21. Build(ls(root), lt, mid);
  22. Build(rs(root), mid + 1, rt);
  23. return ;
  24. }
  25.  
  26. void PushDown(int root, int lt, int rt) {
  27. if (lazya[root] == 0 && lazym[root] == 1) return ;
  28. (tree[ls(root)] *= lazym[root]) %= p;
  29. (lazym[ls(root)] *= lazym[root]) %= p;
  30. (lazya[ls(root)] *= lazym[root]) %= p;
  31. (tree[rs(root)] *= lazym[root]) %= p;
  32. (lazym[rs(root)] *= lazym[root]) %= p;
  33. (lazya[rs(root)] *= lazym[root]) %= p;
  34. lazym[root] = 1;
  35. int mid = lt + ((rt - lt) >> 1);
  36. (tree[ls(root)] += (mid - lt + 1) * 1ll * lazya[root]) %= p;
  37. (lazya[ls(root)] += lazya[root]) %= p;
  38. (tree[rs(root)] += (rt - mid) * 1ll * lazya[root]) %= p;
  39. (lazya[rs(root)] += lazya[root]) %= p;
  40. lazya[root] = 0;
  41. return ;
  42. }
  43.  
  44. ll GetSeq(int root, int lt, int rt, int lq, int rq) {
  45. if (lt == lq && rt == rq) {
  46. return tree[root];
  47. }
  48. PushDown(root, lt, rt);
  49. int mid = lt + ((rt - lt) >> 1);
  50. if (rq <= mid) {
  51. return GetSeq(ls(root), lt, mid, lq, rq);
  52. } else if (lq > mid) {
  53. return GetSeq(rs(root), mid + 1, rt, lq, rq);
  54. } else {
  55. return GetSeq(ls(root), lt, mid, lq, mid) + GetSeq(rs(root), mid + 1, rt, mid + 1, rq);
  56. }
  57. }
  58.  
  59. void AddSeq(int root, int lt, int rt, int lq, int rq, int val) {
  60. if (lt == lq && rt == rq) {
  61. (tree[root] += (rt - lt + 1) * 1ll * val) %= p;
  62. (lazya[root] += val) %= p;
  63. return ;
  64. }
  65. PushDown(root, lt, rt);
  66. int mid = lt + ((rt - lt) >> 1);
  67. if (rq <= mid) {
  68. AddSeq(ls(root), lt, mid, lq, rq, val);
  69. } else if (lq > mid) {
  70. AddSeq(rs(root), mid + 1, rt, lq, rq, val);
  71. } else {
  72. AddSeq(ls(root), lt, mid, lq, mid, val);
  73. AddSeq(rs(root), mid + 1, rt, mid + 1, rq, val);
  74. }
  75. Merge(root);
  76. return ;
  77. }
  78.  
  79. void MulSeq(int root, int lt, int rt, int lq, int rq, int val) {
  80. if (lt == lq && rt == rq) {
  81. (tree[root] *= val) %= p;
  82. (lazya[root] *= val) %= p;
  83. (lazym[root] *= val) %= p;
  84. return ;
  85. }
  86. PushDown(root, lt, rt);
  87. int mid = lt + ((rt - lt) >> 1);
  88. if (rq <= mid) {
  89. MulSeq(ls(root), lt, mid, lq, rq, val);
  90. } else if (lq > mid) {
  91. MulSeq(rs(root), mid + 1, rt, lq, rq, val);
  92. } else {
  93. MulSeq(ls(root), lt, mid, lq, mid, val);
  94. MulSeq(rs(root), mid + 1, rt, mid + 1, rq, val);
  95. }
  96. Merge(root);
  97. return ;
  98. }
  99.  
  100. int main() {
  101. freopen("easilysegmenttree.in", "r", stdin);
  102. freopen("easilysegmenttree.out", "w", stdout);
  103. scanf("%d %d %d", &n, &m, &p);
  104. Build(1, 1, n);
  105. while (m--) {
  106. int op, l, r, v;
  107. scanf("%d %d %d", &op, &l, &r);
  108. if (op == 1) {
  109. scanf("%d", &v);
  110. AddSeq(1, 1, n, l, r, v);
  111. } else if (op == 2) {
  112. scanf("%d", &v);
  113. MulSeq(1, 1, n, l, r, v);
  114. } else if (op == 3) {
  115. printf("%lld\n", GetSeq(1, 1, n, l, r) % p);
  116. } else {
  117. printf("QwQ");
  118. }
  119. }
  120. return 0;
  121. }