接着提出新的问题:
A l r x把[l,r]加上x
Q l r 求[l,r]的总和
这该怎么办呢?显然先前所提出的方法已不再使用,我们深度分析:
令加x之前sum[i]=segma(a[i]),加x之后sum'[i]=segma(a[i]).
如果给[l,r]加上x,会对sum产生怎样的影响?
1.i<l sum'[i]=sum[i]
2.l<=i<=r sum'[i]=sum[i]+x*(i-l+1)=sum[i]+x*i-(l-1)*x
3.r<i sum'[i]=sum[i]+x*(r-l+1)
显然,对于1,3我们可以很简单的解决,只需借助imos算法即可,那么2呢?
沿用往昔的分析思路:把变的拎出来,不变的固定。
那么对于sum'[i]=sum[i]+x*i-x*(l-1)
我们可以维护sum1[i]=x,sum2[i]=sum[i]-x*(l-1)
那么sum'[i]=i*sum1[i]+sum2[i]
而sum1[i],sum2[i]都不含有可变的量,可以用树状数组维护。
参考程序:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=110000;
int n;
struct BitTree{
int a[maxn];
int n;
void init(int n){
this->n=n;
memset(a,0,sizeof(a));
}
void add(int x,int k){
while (x<=n){
a[x]+=k;
x+=x&(-x);
}
}
int query(int x){
int sum=0;
while (x>0){
sum+=a[x];
x-=x&(-x);
}
return sum;
}
}bit0,bit1;
int main(){
int T;
scanf("%d%d",&n,&T);
bit0.init(n);bit1.init(n);
while (T--){
char cmd;
int L,R,x;
scanf("\n%c%d%d",&cmd,&L,&R);
if (cmd=='A'){
scanf("%d",&x);
bit0.add(L,-x*(L-1));
bit1.add(L,x);
bit0.add(R+1,x*R);
bit1.add(R+1,-x);
}else{
int t=bit0.query(R)+bit1.query(R)*R;
t-=bit0.query(L-1)+bit1.query(L-1)*(L-1);
printf("%d\n",t);
}
}
return 0;
}