#include <stdio.h>
#include <string.h>
__int64 c1[100000+10];
__int64 c2[100000+10];
__int64 a[100000+10];
int n,q;
int lowbit(int k)
{
return (k&(-k));
}
__int64 sum(__int64 *c,int x) //求和
{
__int64 ret = 0;
while(x>0)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
void add(__int64 *c,int x,__int64 d) //修改节点的值
{
while(x<=n)
{
c[x]+=d;
x+=lowbit(x);
}
}
int main()
{
scanf("%d%d",&n,&q);
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
int i,j;
a[0]=0;
for(i=1;i<=n;i++)
{
int rec;
scanf("%d",&rec);
a[i]=a[i-1]+rec;
}
for(i=1;i<=q;i++)
{
char qc[5];
scanf("%s",qc);
if(qc[0]=='Q')
{
int a1,b1;
scanf("%d%d",&a1,&b1);
__int64 ans;
ans=a[b1]-a[a1-1];
ans+=b1*sum(c1,b1)-sum(c2,b1); //加上到b1处所能增加的所有的和
ans-=(a1-1)*sum(c1,a1-1)-sum(c2,a1-1); //减去到a1-1处所能增加的所有的和
printf("%I64d\n",ans);
}
if(qc[0]=='C')
{
int a1,b1,d;
scanf("%d%d%d",&a1,&b1,&d);
add(c1,a1,d);
add(c1,b1+1,-d);
add(c2,a1,d*(a1-1)); //这边相当于保留(i-1)*d,就是所要减去的那部分。
add(c2,b1+1,-d*b1); //当超过其范围时,c2中保存的就应该是负的这一段的和,这样减去其时,就可以直接把这一段加上去了
}
}
return 0;
}
POJ 3468 A Simple Problem with Integers 树状数组解法
最新推荐文章于 2019-08-27 18:47:37 发布