懒标记:
#include<iostream> #include<cstdio> #include<cstring> #define ll long long #define ls now<<1 #define rs now<<1|1 #define N 100007 using namespace std; ll n,m,judge,a[N],x,y,z; ll tree[N*4],lzt[N*4]; ll read() { ll ans=0; char ch=getchar(),last=' '; while(ch>'9'||ch<'0')last=ch,ch=getchar(); while(ch>='0'&&ch<='9')ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar(); return last=='-'?-ans:ans; } void fix(ll now,ll l,ll r,ll k) { lzt[now]=lzt[now]+k; tree[now]=tree[now]+k*(r-l+1); } void pushup(ll now){tree[now]=tree[ls]+tree[rs];} void pushdown(ll now,ll l,ll r) { ll mid=(l+r)>>1; fix(ls,l,mid,lzt[now]); fix(rs,mid+1,r,lzt[now]); lzt[now]=0; } void build(ll now,ll l,ll r) { if(l==r) { tree[now]=a[l]; return; } ll mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); pushup(now); } void update(ll now,ll l,ll r,ll L,ll R,ll k) { if(l>=L&&r<=R) { tree[now]+=k*(r-l+1); lzt[now]+=k; return; } pushdown(now,l,r); ll mid=(l+r)>>1; if(L<=mid)update(ls,l,mid,L,R,k); if(R>mid)update(rs,mid+1,r,L,R,k); pushup(now); } ll query(ll now,ll l,ll r,ll L,ll R) { ll sumnow=0; if(l>=L&&r<=R)return tree[now]; ll mid=(l+r)>>1; pushdown(now,l,r); if(L<=mid)sumnow+=query(ls,l,mid,L,R); if(R>mid)sumnow+=query(rs,mid+1,r,L,R); return sumnow; } int main(){ n=read(),m=read(); for(ll i=1;i<=n;i++) a[i]=read(); build(1,1,n); for(ll i=1;i<=m;i++) { judge=read(); if(judge==1) { x=read(),y=read(),z=read(); update(1,1,n,x,y,z); } else { x=read(),y=read(); printf("%lld ",query(1,1,n,x,y)); } } return 0; }
标记永久化:
#include<iostream> #include<cstdio> #include<cstring> #define ll long long #define ls now<<1 #define rs now<<1|1 #define N 100007 using namespace std; ll tree[N*4],lzt[N*4],a[N]; ll n,m; ll read() { ll ans=0; char ch=getchar(),last=' '; while(ch>'9'||ch<'0')last=ch,ch=getchar(); while(ch>='0'&&ch<='9')ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar(); return last=='-'?-ans:ans; } void pushup(ll now){tree[now]=tree[ls]+tree[rs];} void build(ll now,ll l,ll r) { if(l==r) { tree[now]=a[l]; return; } ll mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); pushup(now); } void update(ll now,ll l,ll r,ll L,ll R,ll k) { tree[now]+=((ll)(min(r,R)-(ll)max(l,L)+1)*k); if(l>=L&&r<=R) { lzt[now]+=k; return; } ll mid=(l+r)>>1; if(L<=mid)update(ls,l,mid,L,R,k); if(R>mid)update(rs,mid+1,r,L,R,k); } ll query(ll now,ll l,ll r,ll L,ll R,ll tag) { if(l>=L&&r<=R) { return tree[now]+((ll)min(r,R)-(ll)max(l,L)+1)*tag; } ll mid=(l+r)>>1; ll sumnow=0; if(L<=mid)sumnow+=query(ls,l,mid,L,R,tag+lzt[now]); if(R>mid)sumnow+=query(rs,mid+1,r,L,R,tag+lzt[now]); return sumnow; } int main(){ n=read(),m=read(); for(ll i=1;i<=n;i++) a[i]=read(); build(1,1,n); ll b,c,d,judge; for(ll i=1;i<=m;i++) { judge=read(); if(judge==1) { b=read(),c=read(),d=read(); update(1,1,n,b,c,d); } else { b=read(),c=read(); printf("%lld ",query(1,1,n,b,c,0)); } } return 0; }