#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define endl '\n'
#define ll long long
#define int long long
using namespace std;
const int N = 1e5 + 10, mod = 1e9 + 7;
struct Tree
{
int l, r;
int sum, xsum, lazy;
} tr[N << 2];
int w[N];
int n, m;
void change(int u, int lazy)
{
tr[u].xsum = (tr[u].xsum%mod + 2 * tr[u].sum * lazy % mod + (tr[u].r - tr[u].l + 1) * lazy % mod * lazy % mod) % mod;
tr[u].sum = (tr[u].sum%mod + (tr[u].r - tr[u].l + 1) * lazy % mod) % mod;
tr[u].lazy += lazy;
tr[u].lazy %= mod;
}
// void change(int u, int x)
// {
// tr[u].xsum = tr[u].xsum + 2 * tr[u].sum * x % mod + (tr[u].r - tr[u].l + 1) * x % mod * x % mod;
// tr[u].xsum %= mod;
// tr[u].sum = tr[u].sum + (tr[u].r - tr[u].l + 1) * x;
// tr[u].sum %= mod;
// tr[u].lazy += x;
// tr[u].lazy %= mod;
// }
void pushdown(int u)
{
if (tr[u].lazy)
{
change(u << 1, tr[u].lazy);
change(u << 1 | 1, tr[u].lazy);
tr[u].lazy = 0;
}
}
void pushup(int u)
{
tr[u].sum = (tr[u << 1].sum % mod + tr[u << 1 | 1].sum % mod) % mod;
tr[u].xsum = (tr[u << 1].xsum % mod + tr[u << 1 | 1].xsum % mod) % mod;
}
void build(int u, int l, int r)
{
if (l == r)
tr[u] = {l, r, w[l], (int)((ll)w[l] * w[l] % mod), 0};
else
{
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u, int l, int r, int x)
{
if (tr[u].l >= l && tr[u].r <= r)
{
change(u, x);
}
else
{
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid)
modify(u << 1, l, r, x);
if (r > mid)
modify(u << 1 | 1, l, r, x);
pushup(u);
}
}
int query(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r)
{
return tr[u].xsum % mod;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
ll res = 0;
if (l <= mid)
res += query(u << 1, l, r);
if (r > mid)
res += query(u << 1 | 1, l, r);
return res % mod;
}
signed main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> w[i];
}
build(1, 1, n);
cin >> m;
while (m--)
{
int op;
int l, r, x;
cin >> op;
if (op == 0)
{
cin >> l >> r >> x;
modify(1, l, r, x);
}
else
{
cin >> l >> r;
cout << query(1, l, r) % mod << endl;
}
}
}
此处涉及公式
注意在pushdown操作中,平方和需要的是区间加之前的区间和的值,所以需要先更新区间平方和,再更新区间和