#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 222222
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)
#define ll long long
long long s[maxn<<2],a[maxn<<2];
void pushdown(int rt,int l,int r)
{
a[ls]+=a[rt];
a[rs]+=a[rt];
s[ls]+=a[rt]*(mid-l+1);
s[rs]+=a[rt]*(r-mid);
a[rt]=0;
}
void ins(int rt,int l,int r,int L,int R,ll w)
{
if(l>R||r<L)return;
if(L<=l&&r<=R)
{
a[rt]+=w;
s[rt]+=w*(r-l+1);
// printf("%d %lld\n",rt,s[rt]);
if(l==r)a[rt]=0;
return;
}
if(a[rt]!=0)pushdown(rt,l,r);
if(mid>=L)ins(ls,l,mid,L,R,w);
if((mid+1)<=R)ins(rs,mid+1,r,L,R,w);
// printf("ls:%d rs:%d s[ls]:%d s[rs]:%d\n",ls,rs,s[ls],s[rs]);
s[rt]=s[ls]+s[rs];
// printf("rt:%d va:%d\n",rt,s[rt]);
}
ll query(int rt,int l,int r,int L,int R)
{
if(l>R||r<L)return 0;
if(L<=l&&r<=R){return s[rt];}
ll res=0;
if(a[rt]!=0)pushdown(rt,l,r);
if(mid>=L)res+=query(ls,l,mid,L,R);
if((mid+1)<=R)res+=query(rs,mid+1,r,L,R);
return res;
}
int main()
{
int x,y,m,n;
ll z;
char ss[5];
while(~scanf("%d%d",&n,&m))
{
memset(a,0,sizeof a);
memset(s,0,sizeof s);
for(int i=1;i<=n;++i)
{
scanf("%lld",&z);
ins(1,1,n,i,i,z);
}
memset(ss,0,sizeof ss);
for(int i=0;i<m;++i)
{
scanf("%s",ss);
if(ss[0]=='Q')
{
int a,b;
scanf("%d%d",&a,&b);
printf("%lld\n",query(1,1,n,a,b));
}
else
{
scanf("%d%d%lld",&x,&y,&z);
ins(1,1,n,x,y,z);
}
}
}
return 0;
}
成段更新 区间求和的模版
纯手打 查错查了一个晚上 build函数没有写 会慢上一点 不过编码量也变小了