在上一道题中,我们用树状数组维护了原序列的差分数组,得到了不同操作对原序列的累计影响:
在这道题中,我们需要求出这些累计影响的前缀和,即:
我们对这个式子变形一下:
为什么能这么变形呢?
我们画图解释:
这样,我们只要维护两个树状数组(i*b[i])和(b[i])的即可.
具体见代码实现:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int n, m;
int a[N], sum[N];
int c0[N], c1[N];//c0维护的是b[i], c1维护的是i * b[i]
int ask(int c[], int x){
int ans = 0;
for (; x; x -= x & -x)
ans += c[x];
return ans;
}
void add(int c[], int x, int y){
for (; x <= n; x += x & -x)
c[x] += y;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i){
cin >> a[i];
sum[i] = sum[i - 1] + a[i];
}
while (m--){
string op;
cin >> op;
if (op == "C"){
int l, r, d;
cin >> l >> r >> d;
add(c0, l, d);
add(c0, r + 1, -d);
add(c1, l, l * d);
add(c1, r + 1, -((r + 1) * d));
} else{
int l, r;
cin >> l >> r;
cout << ((r + 1) * ask(c0, r) - ask(c1, r)) - (l * ask(c0, l - 1) - ask(c1, l - 1)) + sum[r] - sum[l - 1] << '\n';
}
}
}