用bit0表示未修改的树状数组,而bit1则是修改后的树状数组。
区间更新:在[l,r]区间上同时加上x可以看成是
在bit0的l位置加上-x(l-1)
在bit1的l位置加上x
在bit0的r+1位置加上xr
在bit1的r+1位置加上-x
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
using namespace std;
long long bit[100100],bit1[100100],n,q;
long long sum(long long *b,int i)
{
long long s = 0;
while (i>0) {
s += b[i];
i -= i&-i;
}
return s;
}
void add(long long *b,int i,int x)
{
while (i<=n) {
b[i] += x;
i += i&-i;
}
}
int main()
{
memset(bit, 0, sizeof(bit));
cin>>n>>q;
for (int i = 1; i<=n; i++) {
long long num;
scanf("%lld",&num);
add(bit,i, num);
}
getchar();
for (int i = 1; i<=q; i++) {
char ch;
ch = getchar();
//cout<<ch<<' ';
if (ch == 'Q') {
int a,b;
scanf("%d%d",&a,&b);
getchar();
long long ans = 0;
ans += sum(bit,b) + sum(bit1,b)*b;
ans -= sum(bit,a-1) + sum(bit1,a-1)*(a-1);//区间求和
printf("%lld\n",ans);
}
if (ch == 'C') {
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
getchar();
add(bit,a, -c*(a - 1));
add(bit1, a,c);
add(bit, b+1,c*b);
add(bit1,b+1, -c);
}
}
return 0;
}