题目大意:跟普通线段树不同的就是需要区间更新;
题目解析:注意懒操作和区间所有元素更新时sum要乘以区间内元素的个数;
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
ll val[400010],lazy[400010];
void pushup(int rt)
{
val[rt]=val[rt<<1]+val[rt<<1|1];
}
void pushdown(int rt,int l,int r)
{
if(lazy[rt]==0) return ;
ll m=(l+r)>>1;
val[rt<<1]+=lazy[rt]*(m-l+1);
val[rt<<1|1]+=lazy[rt]*(r-m);
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
lazy[rt]=0;
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%lld",&val[rt]);
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
ll query(int le,int ri,int l,int r,int rt)
{
if(le<=l&&ri>=r)
{
return val[rt];
}
pushdown(rt,l,r);
int m=(l+r)>>1;
ll ans=0;
if(le<=m) ans+=query(le,ri,lson);
if(ri>m) ans+=query(le,ri,rson);
return ans;
}
void update(int le,int ri,ll mon,int l,int r,int rt)
{
if(le<=l&&ri>=r)
{
val[rt]+=(r-l+1)*mon;
lazy[rt]+=mon;
return ;
}
pushdown(rt,l,r);
int m=(l+r)>>1;
if(le<=m) update(le,ri,mon,lson);
if(ri>m) update(le,ri,mon,rson);
pushup(rt);
}
int main()
{
int cas,c,n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(val,0,sizeof(val));
memset(lazy,0,sizeof(lazy));
build(1,n,1);
while(m--)
{
char ch[3];
scanf("%s",&ch[1]);
if(ch[1]=='C')
{
int sta,end,val;
scanf("%d%d%d",&sta,&end,&val);
update(sta,end,val,1,n,1);
}
else
{
int v,x;
scanf("%d%d",&x,&v);
printf("%lld\n",query(x,v,1,n,1));
}
}
}
return 0;
}