Advertisement
ivnikkk

Untitled

Jan 17th, 2023
1,111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.88 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. };
  62. struct Segtree {
  63.     int n;
  64.     vector<Node> t;
  65.     Segtree(int _n, vector<int>& a) : n(_n) {
  66.         t.resize(4 * _n);
  67.         build(1, 0, _n - 1, a);
  68.     }
  69.     void build(int v, int tl, int tr, vector<int>& a) {
  70.         if (tl == tr) {
  71.             Mint up(1), pw(tl + 1), val(a[tl]);
  72.             for (int _ = 0; _ < 3; _++) {
  73.                 t[v].sum[_] = val * up;
  74.                 up = (up * pw);
  75.             }
  76.             return;
  77.         }
  78.         int tm = (tl + tr) / 2;
  79.         build(v * 2, tl, tm, a);
  80.         build(v * 2 + 1, tm + 1, tr, a);
  81.         for (int _ = 0; _ < 3; _++) {
  82.             t[v].sum[_] = (t[v * 2].sum[_] + t[v * 2 + 1].sum[_]);
  83.         }
  84.     }
  85.     void push(int v, int tl, int tr) {
  86.         if (t[v].push == -1) { return; }
  87.         t[v].sum[0] = Mint(t[v].push) * (tr - tl + 1ll);
  88.         t[v].sum[1] = seg_ari(tl + 1, tr + 1) * t[v].push;
  89.         t[v].sum[2] = seg_sqSum(tl + 1, tr + 1) * t[v].push;
  90.         if (v * 2 + 1 < (int)t.size()) {
  91.             t[v * 2].push = t[v].push;
  92.             t[v * 2 + 1].push = t[v].push;
  93.         }
  94.         t[v].push = -1;
  95.     }
  96.     void update(int v, int tl, int tr, int l, int r, int val) {
  97.         push(v, tl, tr);
  98.         if (tl > r || tr < l) { return; }
  99.         if (tl >= l && tr <= r) {
  100.             t[v].push = val;
  101.             push(v, tl, tr);
  102.             return;
  103.         }
  104.         int tm = (tl + tr) / 2;
  105.         update(v * 2, tl, tm, l, r, val);
  106.         update(v * 2 + 1, tm + 1, tr, l, r, val);
  107.         for (int _ = 0; _ < 3; _++) {
  108.             t[v].sum[_] = (t[v * 2].sum[_] + t[v * 2 + 1].sum[_]);
  109.         }
  110.     }
  111.     void update(int l, int r, int val) {
  112.         update(1, 0, n - 1, l, r, val);
  113.     }
  114.     Node get_sum(int v, int tl, int tr, int l, int r) {
  115.         push(v, tl, tr);
  116.         if (tl > r || tr < l) { return Node(); }
  117.         if (tl >= l && tr <= r) { return t[v]; }
  118.         int tm = (tl + tr) / 2;
  119.         Node ql = get_sum(v * 2, tl, tm, l, r);
  120.         Node qr = get_sum(v * 2 + 1, tm + 1, tr, l, r);
  121.         Node res;
  122.         for (int _ = 0; _ < 3; _++) {
  123.             res.sum[_] = (ql.sum[_] + qr.sum[_]);
  124.         }
  125.         return res;
  126.     }
  127.     Node get_sum(int l, int r) {
  128.         return get_sum(1, 0, n - 1, l, r);
  129.     }
  130. };
  131. signed main() {
  132. #ifdef _DEBUG
  133.     freopen("input.txt", "r", stdin);
  134.     freopen("output.txt", "w", stdout);
  135. #endif
  136.     ios_base::sync_with_stdio(false);
  137.     cin.tie(nullptr);
  138.     int n, q; cin >> n >> q;
  139.     vector<int> a(n);
  140.     for (int i = 0; i < n; i++) {
  141.         cin >> a[i];
  142.     }
  143.     Segtree T(n, a);
  144.     auto count_function = [&](int l, int r) {
  145.         Node sm = T.get_sum(l, r);
  146.         return (sm.sum[0] * l * l - (sm.sum[1] * 2ll * l) + sm.sum[2]).z;
  147.     };
  148.     while (q--) {
  149.         int tp; cin >> tp;
  150.         if (tp == 1) {
  151.             int l, r, x; cin >> l >> r >> x;
  152.             l--, r--;
  153.             T.update(l, r, x);
  154.         }
  155.         if (tp == 2) {
  156.             int l, r; cin >> l >> r;
  157.             l--, r--;
  158.             cout << count_function(l, r) << '\n';
  159.         }
  160.     }
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement