模板线段树1ac代码改了一点
#include<iostream>
#include<cstdio>
using namespace std;
long long n,m,a[100010],sum[400040],l[400040],r[400040],add[400040],x,y,k,q;
inline int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
void make(int p,int le,int ri)
{
l[p]=le,r[p]=ri;
if(le==ri)
{
sum[p]=a[le];
return;
}
long long mid=(ri+le)>>1;
make(p*2,le,mid);
make(p*2+1,mid+1,ri);
sum[p]=sum[p*2]+sum[p*2+1];
}
void print(int p)
{
cout<<p<<" "<<l[p]<<" "<<r[p]<<" "<<sum[p]<<" "<<add[p]<<"\n";
if(l[p]==r[p])return ;
print(p*2);
print(p*2+1);
}
void pud(int p)
{
if(add[p]!=0)
{
long long pp=p*2;
if(r[p]!=l[p])
{
add[p*2]+=add[p];
add[p*2+1]+=add[p];
sum[pp]+=add[p]*(r[pp]-l[pp]+1);
sum[pp+1]+=add[p]*(r[pp+1]-l[pp+1]+1);
}
add[p]=0;
}
}
long long search(int p,int le,int ri)
{
pud(p);
if(l[p]>=le&&r[p]<=ri)return sum[p];
long long mid=(r[p]+l[p])>>1;
if(mid<le)return search(p*2+1,le,ri);
else if(mid>=ri)return search(p*2,le,ri);
else return search(p*2+1,le,ri)+search(p*2,le,ri);
}
void change(int p,int le,int ri,int d)
{
if(l[p]>=le&&r[p]<=ri)
{
add[p]+=d;
sum[p]+=d*(r[p]-l[p]+1);
return;
}
pud(p);
long long mid=(r[p]+l[p])>>1;
if(mid<le)change(p*2+1,le,ri,d);
else if(mid>=ri)change(p*2,le,ri,d);
else change(p*2+1,le,ri,d),change(p*2,le,ri,d);
sum[p]=sum[p*2]+sum[p*2+1];
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
make(1,1,n);
for(int i=1;i<=m;i++)
{
q=read();
if(q==1)
{
x=read(),y=read(),k=read();
change(1,x,y,k);
}
if(q==2)
{
k=read();
change(1,1,1,k);
}
if(q==3)
{
k=read();
change(1,1,1,-k);
}
if(q==4)
{
x=read(),y=read();
cout<<search(1,x,y)<<"\n";
}
if(q==5)cout<<search(1,1,1)<<"\n";
}
}