题目:https://www.luogu.org/problemnew/show/P3372
线段树模板。
代码如下:
#include<iostream> #include<cstdio> using namespace std; long long n,m,a[100005],ct; struct N{ long long lazy,sum; long long ls,rs; }p[200005]; void pushdown(long long cur,long long l,long long r) { long long mid=(l+r)/2; long long lson=p[cur].ls,rson=p[cur].rs; p[lson].lazy+=p[cur].lazy; p[rson].lazy+=p[cur].lazy; p[lson].sum+=p[cur].lazy*(mid-l+1); p[rson].sum+=p[cur].lazy*(r-mid); p[cur].lazy=0; } void pushup(long long cur) { long long lson=p[cur].ls,rson=p[cur].rs; p[cur].sum=p[lson].sum+p[rson].sum; } void build(long long l,long long r,long long cur) { if(l==r) { p[cur].sum=a[l]; p[cur].ls=-1;p[cur].rs=-1; return; } long long mid=(l+r)/2; p[cur].ls=++ct;p[cur].rs=++ct; build(l,mid,p[cur].ls);build(mid+1,r,p[cur].rs); pushup(cur); } void add(long long l,long long r,long long L,long long R,long long c,long long cur) { if(l>=L&&r<=R) { p[cur].lazy+=c; p[cur].sum+=c*(r-l+1); return; } pushdown(cur,l,r);// long long mid=(l+r)/2; if(mid<R)add(mid+1,r,L,R,c,p[cur].rs); if(mid>=L)add(l,mid,L,R,c,p[cur].ls); pushup(cur);// } long long query(long long l,long long r,long long L,long long R,long long cur) { long long tot=0; if(l>=L&&r<=R) return p[cur].sum; long long mid=(l+r)/2; pushdown(cur,l,r); if(mid<R)tot+=query(mid+1,r,L,R,p[cur].rs); if(mid>=L)tot+=query(l,mid,L,R,p[cur].ls); return tot; } int main() { scanf("%lld%lld",&n,&m); for(long long i=1;i<=n;i++) scanf("%lld",&a[i]); long long rt=++ct; build(1,n,rt); long long d,x,y,k; for(long long i=1;i<=m;i++) { scanf("%d",&d); if(d==1) { scanf("%lld%lld%lld",&x,&y,&k); add(1,n,x,y,k,rt); } if(d==2) { scanf("%lld%lld",&x,&y); printf("%lld\n",query(1,n,x,y,rt)); } } return 0; }