问题引入
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/719e103690d3453582c60797fb5f5f6e.png)
分析
- 仍然需要差分进行区间修改,差分数组为b
- 然后求单点的值,维护tr1数组
- 考虑:区间1~x上的tr1数组得和应该如何计算
- 由此看来,sum 可转换为两个前缀和的差,因此也就需要维护tr2来记录i*bi的前缀和
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a3fb356bbca948799f5c8ae73378a0f3.png)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m;
typedef long long LL;
LL tr1[N], tr2[N];
LL a[N];
int lowbit(int x) {
return x & -x;
}
void add(LL tr[], int x, LL c) {
for (int i = x; i <= n; i += lowbit(i)) {
tr[i] += c;
}
}
LL get_sum(LL tr[], int x) {
LL res = 0;
for (int i = x; i; i -= lowbit(i))
res += tr[i];
return res;
}
LL get_prefix(int x) {
LL res = 0;
return (x + 1) * get_sum(tr1, x) - get_sum(tr2, x);
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++ ) {
cin >> a[i];
add(tr1, i, a[i] - a[i - 1]);
add(tr2, i, (LL)i * (a[i] - a[i - 1]));
}
while (m--) {
string s;
int l, r, d;
cin >> s >> l >> r;
if (s == "Q") {
cout << (LL) get_prefix(r) - get_prefix(l - 1) << endl;
} else {
cin >> d;
add(tr1, l, d);
add(tr1, r + 1, -d);
add(tr2, l, (LL)l * d);
add(tr2, r + 1, (LL) - d * (r + 1));
}
}
return 0;
}