B Day 1 ECPC 24

 avatar
unknown
c_cpp
a year ago
3.2 kB
5
Indexable
#include <bits/stdc++.h>

using namespace std;

#define ll long long

void FIO() {
#ifndef ONLINE_JUDGE
    freopen("../in.txt", "r", stdin);
    freopen("../out.txt", "w", stdout);
#endif
}

const ll M = 1e9 + 7;

struct seg {
    ll sum, sum_2, sum_3;
};

struct segment_tree {
    ll sz;
    vector<seg> tree;
    vector<ll> lazy;

    void init(ll n) {
        sz = 1;
        while (sz < n) sz *= 2;
        tree.assign(2 * sz, {0, 0, 0});
        lazy.assign(2 * sz, 0);
    }

    seg merge(seg a, seg b) {
        return {
                (a.sum + b.sum) % M,
                (a.sum_2 + b.sum_2) % M,
                (a.sum_3 + b.sum_3) % M
        };
    }

    void propagate(ll x, ll lx, ll rx) {
        if (lazy[x]) {
            ll sum = tree[x].sum,
                    sum_2 = tree[x].sum_2,
                    sum_3 = tree[x].sum_3, v = lazy[x];
            tree[x].sum = (sum + v * (rx - lx) % M) % M;
            tree[x].sum_2 = (sum_2 +
                             v * v % M * (rx - lx) % M) % M +
                            2 * v % M * sum % M;
            tree[x].sum_3 = (sum_3 +
                             3 * v * sum_2 % M) % M +
                            (3 * v * v % M * sum % M +
                             v * v % M * v % M * (rx - lx) % M) % M;
            tree[x].sum_2 %= M;
            tree[x].sum_3 %= M;
            if (rx - lx > 1) {
                lazy[2 * x + 1] += lazy[x];
                lazy[2 * x + 2] += lazy[x];
            }
            lazy[x] = 0;
        }
    }

    void update(ll x, ll lx, ll rx, ll l, ll r, ll v) {
        propagate(x, lx, rx);
        if (lx >= r || l >= rx) return;
        if (l <= lx && rx <= r) {
            lazy[x] += v;
            propagate(x, lx, rx);
            return;
        }
        ll m = (lx + rx) / 2;
        update(2 * x + 1, lx, m, l, r, v);
        update(2 * x + 2, m, rx, l, r, v);
        tree[x] = merge(tree[2 * x + 1], tree[2 * x + 2]);
    }

    void update(ll l, ll r, ll v) {
        update(0, 0, sz, l, r, v);
    }

    seg query(ll x, ll lx, ll rx, ll l, ll r) {
        propagate(x, lx, rx);
        if (lx >= r || l >= rx) return {0, 0, 0};
        if (l <= lx && rx <= r) return tree[x];
        ll m = (lx + rx) / 2;
        seg left = query(2 * x + 1, lx, m, l, r);
        seg right = query(2 * x + 2, m, rx, l, r);
        return merge(left, right);
    }

    ll query(ll l, ll r) {
        return query(0, 0, sz, l, r).sum_3;
    };
};

void solve() {
    ll n;
    cin >> n;
    segment_tree st;
    st.init(n + 10);
    for (ll i = 0; i < n; i++) {
        ll x;
        cin >> x;
        st.update(i, i + 1, x);
    }
    ll q;
    cin >> q;
    while (q--) {
        ll t;
        cin >> t;
        if (t == 1) {
            ll l, r, v;
            cin >> l >> r >> v;
            --l;
            st.update(l, r, v);
        } else {
            ll l, r;
            cin >> l >> r;
            --l;
            cout << st.query(l, r) << endl;
        }
    }
}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    FIO();

    ll t = 1;
//    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
Editor is loading...
Leave a Comment