matistjati

Untitled

Jun 23rd, 2026
12
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.47 KB | None | 0 0
  1. using namespace std;
  2. #include <bits/stdc++.h>
  3.  
  4. using ll = long long;
  5.  
  6. const ll mod = 1e9 + 7;
  7. ll euclid(ll a, ll b, ll &x, ll &y) {
  8. if (!b) return x = 1, y = 0, a;
  9. ll d = euclid(b, a % b, y, x);
  10. return y -= a/b * x, d;
  11. }
  12.  
  13. struct Mod {
  14. ll x;
  15. Mod(ll xx) : x(xx) {}
  16. Mod operator+(Mod b) { return Mod((x + b.x) % mod); }
  17. Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); }
  18. Mod operator*(Mod b) { return Mod((x * b.x) % mod); }
  19. Mod operator/(Mod b) { return *this * invert(b); }
  20. Mod invert(Mod a) {
  21. ll x, y, g = euclid(a.x, mod, x, y);
  22. assert(g == 1); return Mod((x + mod) % mod);
  23. }
  24. Mod operator^(ll e) {
  25. if (!e) return Mod(1);
  26. Mod r = *this ^ (e / 2); r = r * r;
  27. return e&1 ? *this * r : r;
  28. }
  29. };
  30.  
  31.  
  32. struct Tree {
  33. vector<Mod> tree;
  34. vector<Mod> lazy;
  35. vector<Mod> prefixI;
  36. int n;
  37.  
  38. Tree(int n, vector<Mod> pfi) : n(n), tree(4 * n, Mod(0)), lazy(4 * n, Mod(0)), prefixI(pfi) {}
  39.  
  40. void push(int x, int l, int r) {
  41. int mid = (l + r) / 2;
  42. tree[x * 2] = tree[x * 2] + lazy[x] * (prefixI[mid] - prefixI[max(0, l - 1)]);
  43. lazy[x * 2] = lazy[x * 2] + lazy[x];
  44. tree[x * 2 + 1] = tree[x * 2 + 1] + lazy[x] * (prefixI[r] - prefixI[mid]);
  45. lazy[x * 2 + 1] = lazy[x * 2 + 1] + lazy[x];
  46. lazy[x] = 0;
  47. }
  48.  
  49. void add(int x, int l, int r, int ql, int qr, Mod v) {
  50. if (l > qr || r < ql) return;
  51. if (l >= ql && r <= qr) {
  52. tree[x] = tree[x] + v * (prefixI[r] - prefixI[l - 1]);
  53. lazy[x] = lazy[x] + v;
  54. return;
  55. }
  56. push(x, l, r);
  57. int mid = (l + r) / 2;
  58. add(x * 2, l, mid, ql, qr, v);
  59. add(x * 2 + 1, mid + 1, r, ql, qr, v);
  60. tree[x] = tree[x * 2] + tree[x * 2 + 1];
  61. }
  62.  
  63. void add(int l, int r, Mod v) { add(1, 0, n - 1, l, r, v); }
  64.  
  65. Mod query(int x, int l, int r, int ql, int qr) {
  66. if (l > qr || r < ql) return 0;
  67. if (l >= ql && r <= qr) return tree[x];
  68. push(x, l, r);
  69. int mid = (l + r) / 2;
  70. return query(x * 2, l, mid, ql, qr) + query(x * 2 + 1, mid + 1, r, ql, qr);
  71. }
  72.  
  73. Mod query(int l, int r) { return query(1, 0, n - 1, l, r); }
  74. };
  75.  
  76. Mod poly(ll l, int i) {
  77. l %= mod;
  78. if (i == 0) return Mod(-l + mod) * Mod(l * l) + Mod(6 * l * l) - Mod(11 * l) + Mod(6);
  79. if (i == 1) return Mod(3 * l * l) - Mod(12 * l) + Mod(11);
  80. if (i == 2) return Mod((-3 * l) % mod + mod) + Mod(6);
  81. else return 1;
  82. }
  83.  
  84.  
  85. int main() {
  86. cin.tie(0)->sync_with_stdio(0);
  87.  
  88. int n, q;
  89. cin >> n >> q;
  90. n += 5;
  91.  
  92. vector<vector<Mod>> sum(4, vector<Mod>(n, Mod(0)));
  93. for (int i = 1; i < n; i++) {
  94. sum[0][i] = sum[0][i - 1] + Mod(1);
  95. sum[1][i] = sum[1][i - 1] + Mod(i);
  96. sum[2][i] = sum[2][i - 1] + Mod(i) * Mod(i);
  97. sum[3][i] = sum[3][i - 1] + Mod(i) * Mod(i) * Mod(i);
  98. }
  99.  
  100. vector<Tree> trees = {
  101. Tree(n, sum[0]),
  102. Tree(n, sum[1]),
  103. Tree(n, sum[2]),
  104. Tree(n, sum[3])
  105. };
  106.  
  107. while (q--) {
  108. int t, l, r;
  109. cin >> t >> l >> r;
  110.  
  111. if (t == 1) {
  112. for (int i = 0; i < 4; i++) trees[i].add(l, r, poly(l, i));
  113. }
  114. else if (t == 2) {
  115. for (int i = 0; i < 4; i++) trees[i].add(l, r, Mod(0) - poly(l, i));
  116. }
  117. else {
  118. Mod v = 0;
  119. for (int i = 0; i < 4; i++) v = v + trees[i].query(l, r);
  120. cout << v.x << "\n";
  121. }
  122. }
  123.  
  124. return 0;
  125. }
  126.  
Advertisement
Add Comment
Please, Sign In to add comment