线段树维护区间和
新学习了线段树,打了线段树维护区间和的模板。
#include<cstdio> #define min(a,b) (a<b?a:b) #define max(a,b) (a>b?a:b) #define MAXNUM 100001 #define INF ((1<<31)-1) #define left(a) (a<<1) #define right(a) ((a<<1)+1) int n,q; long long arr[MAXNUM]; struct SegTreeNode{ long long val; long long lazy; SegTreeNode(){ val=0; lazy=0; } }node[MAXNUM*5]; void tree_update(int root){ long long a=node[left(root)].val,b=node[right(root)].val; node[root].val=a+b; return; } void lazy_push(int root,int l,int r){ node[left(root)].lazy+=node[root].lazy; node[right(root)].lazy+=node[root].lazy; node[root].val+=(r-l+1)*node[root].lazy; node[root].lazy=0; } void tree_build(int root,long long arr[],int bl,int br){ node[root].lazy=0; if(bl==br) node[root].val=arr[bl]; else{ int mid=(bl+br)/2; tree_build(left(root),arr,bl,mid); tree_build(right(root),arr,mid+1,br); tree_update(root); } return; } void tree_add(int root,int al,int ar,int l,int r,long long k){ if(r<al||ar<l) return; if(l==al&&r==ar){ node[root].lazy+=k; return; } lazy_push(root,l,r); int mid=(l+r)/2; if(mid>=al) tree_add(left(root),al,min(mid,ar),l,mid,k); if(mid<ar) tree_add(right(root),max(mid+1,al),ar,mid+1,r,k); lazy_push(left(root),l,mid); lazy_push(right(root),mid+1,r); tree_update(root); return; } long long ques(int root,int ql,int qr,int l,int r){ if(l>r) return 0; if(l==ql&&r==qr) return node[root].lazy*(r-l+1)+node[root].val; lazy_push(root,l,r); int mid=(l+r)/2; long long ans=0; if(mid>=ql) ans+=ques(left(root),ql,min(mid,qr),l,mid); if(mid<qr) ans+=ques(right(root),max(mid+1,ql),qr,mid+1,r); return ans; } int main(){ scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%lld",&arr[i]); tree_build(1,arr,1,n); while(q--){ int p,x,y; long long k; scanf("%d",&p); if(p==1){ scanf("%d%d%lld",&x,&y,&k); tree_add(1,x,y,1,n,k); } if(p==2){ scanf("%d%d",&x,&y); printf("%lld\n",ques(1,x,y,1,n)); } } return 0; }
就是这样了。