https://ac.nowcoder.com/acm/contest/200/B
题解:线段树,注意,我一开始的时候写错了,一开始build的时候lazy数组的初始化搞错了,后来又发现在每一次pushdown的时候都要进行乘法和加法两个lazy的判别(之前我是分flag,只对一种判别)。
#include
#define MID (l+r)>>1
#define lson step<<1
#define rson step<<1|1
#define LL long long
using namespace std;
const int maxn=10005;
int n,m;
LL a[maxn],pf[maxn<<2],sum[maxn<<2];
int lazy1[maxn<<2],lazy2[maxn<<2];
void pushup(int step)
{
sum[step]=sum[lson]+sum[rson];
pf[step]=pf[lson]+pf[rson];
}
void pushdown(int l,int r,int flag,int step)
{
int mid=MID;
if(lazy2[step]!=1)
{
lazy2[lson]*=lazy2[step];lazy2[rson]*=lazy2[step];
pf[lson]*=lazy2[step]*lazy2[step];
pf[rson]*=lazy2[step]*lazy2[step];
sum[lson]*=lazy2[step];
sum[rson]*=lazy2[step];
lazy2[step]=1;
}
if(lazy1[step])
{
lazy1[lson]+=lazy1[step];lazy1[rson]+=lazy1[step];
pf[lson]+=lazy1[step]*lazy1[step]*(mid-l+1)+2*lazy1[step]*sum[lson];
pf[rson]+=lazy1[step]*lazy1[step]*(r-mid)+2*lazy1[step]*sum[rson];
sum[lson]+=(mid-l+1)*lazy1[step];
sum[rson]+=(r-mid)*lazy1[step];
lazy1[step]=0;
}
}
void build(int l,int r,int step)
{
lazy1[step]=0;
lazy2[step]=1;
if(l==r)
{
sum[step]=a[l];
pf[step]=a[l]*a[l];
return ;
}
int mid=MID;
build(l,mid,lson);
build(mid+1,r,rson);
pushup(step);
}
void update(int l,int r,int left,int right,int flag,int x,int step)
{
if(left<=l&&right>=r)
{
if(flag==4)
{
lazy1[step]+=x;
pf[step]+=x*x*(r-l+1)+2*x*sum[step];
sum[step]+=(r-l+1)*x;
}
else
{
lazy2[step]*=x;
sum[step]*=x;
pf[step]*=x*x;
}
return ;
}
int mid=MID;
pushdown(l,r,flag,step);
if(left<=mid)
{
update(l,mid,left,right,flag,x,lson);
}
if(right>mid)
{
update(mid+1,r,left,right,flag,x,rson);
}
pushup(step);
}
LL query(int l,int r,int left,int right,int flag,int step)
{
if(l==left&&r==right)
{
if(flag==1) return sum[step];
if(flag==2) return pf[step];
}
int mid=MID;
pushdown(l,r,flag,step);
LL res=0;
if(right<=mid)
res+=query(l,mid,left,right,flag,lson);
else if(left>mid)
res+=query(mid+1,r,left,right,flag,rson);
else
{
res+=query(l,mid,left,mid,flag,lson);
res+=query(mid+1,r,mid+1,right,flag,rson);
}
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
build(1,n,1);
LL ans;
for(int i=1;i<=m;i++)
{
int k,x,l,r;
cin>>k;
if(k==1||k==2)
{
cin>>l>>r;
ans=query(1,n,l,r,k,1);
cout << ans << endl;
}
else
{
cin>>l>>r>>x;
update(1,n,l,r,k,x,1);
}
}
return 0;
}