码量较大的数据结构……调起来也比较费劲……需要注意各个变量名不要写错
//线段树板子 单点修改+区间修改+区间查询(含lazy标记) #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #define LL long long #define MAXN 1000000 using namespace std; inline int read() { int f=1,x=0; char ch=getchar(); while(ch<'0' || ch>'9') {if(ch=='-') f=-1; ch=getchar();} while(ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,q; int a[MAXN+5]; LL seg_tree[MAXN*4+5],lazy_tag[MAXN*4+5]; void add(int l,int r,int k,int num)//lazy与区间和 { lazy_tag[num]+=k; seg_tree[num]+=(r-l+1)*k; } void push_down(int l,int r,int mid,int num)//lazy标记下传 { if(!lazy_tag[num]) return ; add(l,mid,lazy_tag[num],num*2); add(mid+1,r,lazy_tag[num],num*2+1); lazy_tag[num]=0; } void p_add(int k,int c,int l,int r,int num)//单点修改 { if(l==r) { seg_tree[num]+=c; return ; } int mid=(l+r)/2; if(k<=mid) p_add(k,c,l,mid,num*2); else p_add(k,c,mid+1,r,num*2+1); seg_tree[num]=seg_tree[num*2]+seg_tree[num*2+1]; } void qadd(int ll,int rr,int k,int l,int r,int num)//区间修改 { if(ll<=l && rr>=r) { add(l,r,k,num); return ; } int mid=(l+r)/2; push_down(l,r,mid,num); if(ll<=mid) qadd(ll,rr,k,l,mid,num*2); if(rr>mid) qadd(ll,rr,k,mid+1,r,num*2+1); seg_tree[num]=seg_tree[num*2]+seg_tree[num*2+1]; } LL qfind(int ll,int rr,int l,int r,int num)//区间查询 { if(ll<=l && r<=rr) { return seg_tree[num]; } int mid=(l+r)/2; LL ans=0; push_down(l,r,mid,num); if(ll<=mid) ans+=qfind(ll,rr,l,mid,num*2); if(rr>mid) ans+=qfind(ll,rr,mid+1,r,num*2+1); return ans; } int main() { int i; n=read(); q=read(); for(i=1;i<=n;i++) { a[i]=read(); p_add(i,a[i],1,n,1); } int f,a,b,k; for(i=1;i<=q;i++) { f=read(); a=read(); b=read(); if(f==1) { k=read(); qadd(a,b,k,1,n,1); } else printf("%lld ",qfind(a,b,1,n,1)); } return 0; }
~NOIP2018 加油~