http://poj.org/problem?id=3468
有了上一题的基础 这题就是小菜了
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAX 100010
using namespace std;
typedef struct
{
long long l;
long long r;
long long sum;
long long cnt; //加法
} Tree;
Tree tree[MAX*10];
long long i,j,m,n,x,y;
long long k;
char ch[3];
long long a[MAX];
void update(long long i) //更新
{
if(tree[i].cnt!=0) //加法
{
tree[i].sum= ((tree[i].sum +(tree[i].r-tree[i].l+1)*tree[i].cnt)) ; //求和
tree[i*2].cnt =(tree[i*2].cnt + tree[i].cnt) ;
tree[i*2+1].cnt=(tree[i*2+1].cnt + tree[i].cnt) ; //往左右子节点更新加法
tree[i].cnt=0; //
}
}
long long build(long long i,long long l,long long r)
{
long long mid;
tree[i].l=l;
tree[i].r=r;
tree[i].sum=0;
tree[i].cnt =0;
if(l==r)
{
tree[i].sum=a[l];
return 0;
}
mid=(l+r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tree[i].sum=(tree[i*2].sum+tree[i*2+1].sum) ;
}
long long ins(long long i,long long x,long long y,long long c) //加法和乘法可以合并
{
long long mid;
update(i);
if ((x<=tree[i].l)&&(y>=tree[i].r))
{
tree[i].cnt=(tree[i].cnt+c) ;
return 0;
}
mid=(tree[i].l+tree[i].r)/2;
if (x<=mid) ins(i*2, x,y,c);
if (y>mid) ins(i*2+1,x,y,c);
update(i*2);
update(i*2+1);
tree[i].sum= (tree[i*2].sum+tree[i*2+1].sum) ;
}
long long cal(long long i,long long x,long long y) //计算
{
long long mid;
long long ans;
update(i);
if ((x<=tree[i].l)&&(y>=tree[i].r))
return (tree[i].sum);
ans=0;
mid=(tree[i].l+tree[i].r)/2;
if (x<=mid) ans=(ans+cal(i*2,x,y)) ;
if (y>mid) ans=(ans+cal(i*2+1,x,y)) ;
update(i*2);
update(i*2+1);
tree[i].sum=(tree[i*2].sum+tree[i*2+1].sum) ;
return ans;
}
int main()
{
scanf("%lld%lld",&n,&m);
for(i=1; i<=n; i++)
scanf("%lld",&a[i]);
build(1,1,n);
for (i=1; i<=m; i++)
{
scanf("%s",ch);
switch(ch[0])
{
case 'C':
{
scanf("%lld%lld%lld",&x,&y,&k); //加法
if(k!=0)
ins(1,x,y,k);
break;
}
case 'Q':
{
scanf("%lld%lld",&x,&y);//查询
printf("%lld\n",cal(1,x,y));
break;
}
}
}
}