Untitled
unknown
plain_text
a year ago
2.8 kB
13
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