线段树区间加模板
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树区间加模板相关的知识,希望对你有一定的参考价值。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define LL long long #define l(x) (x<<1) #define r(x) ((x<<1)|1) using namespace std; struct Tre { LL sum,tag; }Tr[500100]; LL a[500100]; void update(LL id) { Tr[id].sum=Tr[l(id)].sum+Tr[r(id)].sum; } void pushdown(LL l,LL r,LL id) { Tr[r(id)].tag+=Tr[id].tag; Tr[l(id)].tag+=Tr[id].tag; Tr[id].sum+=(r-l+1)*Tr[id].tag; Tr[id].tag=0; } void build(LL l,LL r,LL id) { if(l==r) { Tr[id].sum=a[l]; return; } LL mid=(l+r)/2; build(mid+1,r,r(id)); build(l,mid,l(id)); update(id); } void add(LL al,LL ar,LL x,LL l,LL r,LL id) { if(l>ar||r<al) return; if(al==l&&ar==r) {Tr[id].tag+=x;return;} pushdown(l,r,id); LL mid=(r+l)/2; if(mid>=al) add(al,min(mid,ar),x,l,mid,l(id)); if(mid<ar) add(max(mid+1,al),ar,x,mid+1,r,r(id)); pushdown(l,mid,l(id)); pushdown(mid+1,r,r(id)); update(id); } LL query(LL al,LL ar,LL l,LL r,LL id) { if(l>r) return 0LL; if(al==l&&ar==r) {return Tr[id].tag*(r-l+1)+Tr[id].sum;} pushdown(l,r,id); LL mid=(r+l)/2; LL t=0; if(mid>=al) t+=query(al,min(mid,ar),l,mid,l(id)); if(mid<ar) t+=query(max(mid+1,al),ar,mid+1,r,r(id)); return t; } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,n,1); while(m--) { int cas; scanf("%d",&cas); if(cas==1) { LL x,y,k; scanf("%lld%lld%lld",&x,&y,&k); add(x,y,k,1,n,1); } else { LL x,y; scanf("%lld%lld",&x,&y); printf("%lld\n",query(x,y,1,n,1)); } } }
以上是关于线段树区间加模板的主要内容,如果未能解决你的问题,请参考以下文章