Untitled

 avatar
unknown
plain_text
a year ago
2.8 kB
10
Indexable
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
struct segTree {
    vector<array<ll, 3>> sg;
    vector<ll> lz;
    ll n, MOD = 1e9 + 7;
    explicit segTree(ll _n) {
        for (n = 1; n < _n; n <<= 1);
        sg.assign(2 * n, {0, 0, 0});
        lz.assign(2 * n, 0);
    }
    ll p3(ll x) {
        x %= MOD;
        return (x * x % MOD) * x % MOD;
    }
    ll p2(ll x) {
        x %= MOD;
        return x * x % MOD;
    }
    void push(ll u, ll sz) {
        ll res;
        //// 3
        res = 0;
        res += sz * p3(lz[u]) % MOD;
        res += sg[u][0] * 3LL % MOD * p2(lz[u]) % MOD;
        res += sg[u][1] * 3LL % MOD * lz[u] % MOD;
        res %= MOD;
        sg[u][2] += res;
        sg[u][2] %= MOD;
        //// 2
        res = 0;
        res += sz * p2(lz[u]) % MOD;
        res += lz[u] * 2LL % MOD * sg[u][0] % MOD;
        res %= MOD;
        sg[u][1] += res;
        sg[u][1] %= MOD;
        /// 1
        sg[u][0] += sz * lz[u];
        sg[u][0] %= MOD;
        //// lazy
        if (u < n)
            for (int i = 0; i < 2; ++i)
                lz[u * 2 + i] += lz[u];
        lz[u] = 0;
    }
    void pull(ll u) {
        if (u < n)
            for (int i = 0; i < 3; ++i)
                sg[u][i] = (sg[u * 2][i] + sg[u * 2 + 1][i]) % MOD;
    }
    void update(int l, int r, ll val) { update(1, l, r, 0, n - 1, val); }
    void update(int u, int l, int r, int cl, int cr, ll val) {
        push(u, cr - cl + 1);
        if (cl > r || cr < l || l > r)
            return;
        if (cl == l && cr == r) {
            lz[u] += val;
            push(u, cr - cl + 1);
            return;
        }
        int m = (cl + cr) / 2;
        update(u * 2, l, min(r, m), cl, m, val);
        update(u * 2 + 1, max(l, m + 1), r, m + 1, cr, val);
        pull(u);
    }
    ll get(int l, int r) { return get(1, l, r, 0, n - 1); }
    ll get(int u, int l, int r, int cl, int cr) {
        push(u, cr - cl + 1);
        if (cl > r || cr < l || l > r)
            return 0;
        if (cl == l && cr == r)
            return sg[u][2];
        int m = (cl + cr) / 2;
        ll res = get(u * 2, l, min(r, m), cl, m);
        res += get(u * 2 + 1, max(l, m + 1), r, m + 1, cr);
        return res % MOD;
    }
};
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    segTree sg(n);
    for (int i = 0, x; i < n; ++i) {
        cin >> x;
        sg.update(i, i, x);
    }
    int q;
    cin >> q;
    for (int i = 0; i < q; ++i) {
        int ty, l, r, x;
        cin >> ty >> l >> r, --l, --r;
        if (ty == 1) {
            cin >> x;
            sg.update(l, r, x);
        } else {
            cout << sg.get(l, r) << "\n";
        }
    }
}
Editor is loading...
Leave a Comment