Advertisement
ivnikkk

Untitled

Jan 17th, 2023
1,040
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.77 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include "bits/stdc++.h"
  3. using namespace std;
  4. #define all(a) a.begin(), a.end()
  5. const int mod = 1e9 + 7;
  6. const int inv6 = 166666668;
  7. const int inv2 = 500000004;
  8. struct Mint {
  9.     int z;
  10.     Mint() : z(0) {}
  11.     Mint(int _z) : z(_z) {}
  12.     Mint operator-(const Mint& other) const {
  13.         int val = z - other.z + mod;
  14.         if (val >= mod) { val -= mod; }
  15.         return Mint(val);
  16.     }
  17.     Mint operator-(const int& other) const {
  18.         int val = z - other + mod;
  19.         if (val >= mod) { val -= mod; }
  20.         return Mint(val);
  21.     }
  22.     Mint operator+(const Mint& other) const {
  23.         int val = z + other.z;
  24.         if (val >= mod) { val -= mod; }
  25.         return Mint(val);
  26.     }
  27.     Mint operator+(const int& other) const {
  28.         int val = z + other;
  29.         if (val >= mod) { val -= mod; }
  30.         return Mint(val);
  31.     }
  32.     Mint operator*(const Mint& other) const {
  33.         int val = (1ll * z * other.z) % mod;
  34.         return Mint(val);
  35.     }
  36.     Mint operator*(const int& other) const {
  37.         int val = (1ll * z * other) % mod;
  38.         return Mint(val);
  39.     }
  40. };
  41. Mint ari(Mint n) {
  42.     return (n + 1ll) * n * inv2;
  43. }
  44. Mint seg_ari(int l, int r) {
  45.     return ari(r) - ari(l - 1);
  46. }
  47. Mint sqSum(Mint n) {
  48.     return n * (n + 1ll) * (n * 2ll + 1ll) * inv6;
  49. }
  50. Mint seg_sqSum(int l, int r) {
  51.     return sqSum(r) - sqSum(l - 1);
  52. }
  53. struct Node {
  54.     Mint sum[3];
  55.     int push;
  56.     Node() : push(-1) {
  57.         sum[0] = Mint();
  58.         sum[1] = Mint();
  59.         sum[2] = Mint();
  60.     }
  61.     Node operator+(const Node& other) {
  62.         Node res;
  63.         for (int _ = 0; _ < 3; _++) {
  64.             res.sum[_] = sum[_] + other.sum[_];
  65.         }
  66.         return res;
  67.     }
  68. };
  69. struct Segtree {
  70.     int n;
  71.     vector<Node> t;
  72.     Segtree(int _n, vector<int>& a) : n(_n) {
  73.         t.resize(4 * _n);
  74.         build(1, 0, _n - 1, a);
  75.     }
  76.     void build(int v, int tl, int tr, vector<int>& a) {
  77.         if (tl == tr) {
  78.             Mint up(1), pw(tl + 1), val(a[tl]);
  79.             for (int _ = 0; _ < 3; _++) {
  80.                 t[v].sum[_] = val * up;
  81.                 up = (up * pw);
  82.             }
  83.             return;
  84.         }
  85.         int tm = (tl + tr) / 2;
  86.         build(v * 2, tl, tm, a);
  87.         build(v * 2 + 1, tm + 1, tr, a);
  88.         t[v] = t[v * 2] = t[v * 2 + 1];
  89.     }
  90.     void push(int v, int tl, int tr) {
  91.         if (t[v].push == -1) { return; }
  92.         t[v].sum[0] = Mint(t[v].push) * (tr - tl + 1ll);
  93.         t[v].sum[1] = seg_ari(tl + 1, tr + 1) * t[v].push;
  94.         t[v].sum[2] = seg_sqSum(tl + 1, tr + 1) * t[v].push;
  95.         if (v * 2 + 1 < (int)t.size()) {
  96.             t[v * 2].push = t[v].push;
  97.             t[v * 2 + 1].push = t[v].push;
  98.         }
  99.         t[v].push = -1;
  100.     }
  101.     void update(int v, int tl, int tr, int l, int r, int val) {
  102.         push(v, tl, tr);
  103.         if (tl > r || tr < l) { return; }
  104.         if (tl >= l && tr <= r) {
  105.             t[v].push = val;
  106.             push(v, tl, tr);
  107.             return;
  108.         }
  109.         int tm = (tl + tr) / 2;
  110.         update(v * 2, tl, tm, l, r, val);
  111.         update(v * 2 + 1, tm + 1, tr, l, r, val);
  112.         t[v] = t[v * 2] + t[v * 2];
  113.     }
  114.     void update(int l, int r, int val) {
  115.         update(1, 0, n - 1, l, r, val);
  116.     }
  117.     Node Query(int v, int tl, int tr, int l, int r) {
  118.         push(v, tl, tr);
  119.         if (tl > r || tr < l) { return Node(); }
  120.         if (tl >= l && tr <= r) { return t[v]; }
  121.         int tm = (tl + tr) / 2;
  122.         return Query(v * 2, tl, tm, l, r) + Query(v * 2 + 1, tm + 1, tr, l, r);
  123.     }
  124.     Node Query(int l, int r) {
  125.         return Query(1, 0, n - 1, l, r);
  126.     }
  127. };
  128. signed main() {
  129. #ifdef _DEBUG
  130.     freopen("input.txt", "r", stdin);
  131.     freopen("output.txt", "w", stdout);
  132. #endif
  133.     ios_base::sync_with_stdio(false);
  134.     cin.tie(nullptr);
  135.     int n, q; cin >> n >> q;
  136.     vector<int> a(n);
  137.     for (int i = 0; i < n; i++) {
  138.         cin >> a[i];
  139.     }
  140.     Segtree T(n, a);
  141.     auto count_function = [&](int l, int r) {
  142.         Node sm = T.Query(l, r);
  143.         return (sm.sum[0] * l * l - (sm.sum[1] * 2ll * l) + sm.sum[2]).z;
  144.     };
  145.     while (q--) {
  146.         int tp; cin >> tp;
  147.         if (tp == 1) {
  148.             int l, r, x; cin >> l >> r >> x;
  149.             l--, r--;
  150.             T.update(l, r, x);
  151.         }
  152.         if (tp == 2) {
  153.             int l, r; cin >> l >> r;
  154.             l--, r--;
  155.             cout << count_function(l, r) << '\n';
  156.         }
  157.     }
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement