这道题wa了好多次....
pushdown的时候一定要注意乘的是上次的lazy不是本次的!!!!!
#include<stdio.h>
#include<string.h>
#include<iostream>
#define ll long long
#define N 100010
using namespace std;
struct node
{
ll l,r,len,lz,val;
} c[5*N];
void build(ll l,ll r,ll rt)
{
c[rt].r=r,c[rt].l=l,c[rt].len=(r-l+1),c[rt].lz=0;
if(r==l)
{
scanf("%lld",&c[rt].val);// printf("ok\n");
return;
}
ll mid=(r+l)/2;
build(l,mid,rt*2);
build(mid+1,r,rt*2+1);
c[rt].val=c[rt*2].val+c[rt*2+1].val;
}
void pushdown(ll rt)
{
if(c[rt].lz!=0)
{
c[rt*2].lz+=c[rt].lz;
c[rt*2+1].lz+=c[rt].lz;
c[rt*2+1].val+=c[rt].lz*c[rt*2+1].len;
c[rt*2].val+=c[rt].lz*c[rt*2].len;
c[rt].lz=0;
}
}
void add(ll l,ll r,ll rt,ll k)
{
if(c[rt].r==r&&c[rt].l==l)
{
c[rt].val+=k*(r-l+1);
c[rt].lz+=k;
return ;
}
if(c[rt].lz!=0)
{
pushdown(rt);
}
ll mid=(c[rt].l+c[rt].r)/2;
if(mid<l)
{
add(l,r,rt*2+1,k);
}
else if(mid>=r)
{
add(l,r,rt*2,k);
}
else
{
add(l,mid,rt*2,k);
add(mid+1,r,rt*2+1,k);
}
c[rt].val=c[rt*2].val+c[rt*2+1].val;
}
ll query(ll rt,ll l,ll r)
{
ll sum;
if(c[rt].l==l&&c[rt].r==r)
{
return c[rt].val;
}
if(c[rt].lz!=0)
{
pushdown(rt);
}
ll mid=(c[rt].l+c[rt].r)/2;
if(mid<l)
{
sum=query(rt*2+1,l,r);
}
else if(mid>=r)
sum=query(rt*2,l,r);
else
{
sum=query(rt*2,l,mid)+query(rt*2+1,mid+1,r);
}
return sum;
}
int main()
{
ll n,m;
while(~scanf("%lld%lld",&n,&m))
{
build(1,n,1);//printf("ok\n");
for(ll i=0; i<m; i++)
{
char ss;
cin>>ss;
if(ss=='Q')
{
ll a,b;
scanf("%lld%lld",&a,&b);
printf("%I64d\n",query(1,a,b));
}
else
{
ll a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
add(a,b,1,c);
}
}
}
}