线段树模板1
题目链接:https://www.luogu.org/problemnew/show/P3372
要注意的是线段树结点数组的大小应为4*n,而不是2*n。
#include<cstdio> using namespace std; typedef long long LL; const int maxn=100005; struct node{ int l,r; LL value,add; }tr[4*maxn]; //注意这里是4倍 int n,m; LL a[maxn],ans; void build(int v,int l,int r){ //建立线段树 tr[v].l=l,tr[v].r=r,tr[v].add=0; if(l==r){ tr[v].value=a[r]; return; } int mid=(l+r)>>1; build(2*v,l,mid); build(2*v+1,mid+1,r); tr[v].value=tr[2*v].value+tr[2*v+1].value; } void spread(int v){ //传递增量 tr[2*v].value+=tr[v].add*(tr[2*v].r-tr[2*v].l+1); tr[2*v+1].value+=tr[v].add*(tr[2*v+1].r-tr[2*v+1].l+1); tr[2*v].add+=tr[v].add; tr[2*v+1].add+=tr[v].add; tr[v].add=0; } void update(int v,int l,int r,LL k){ //更新 if(tr[v].l==l&&tr[v].r==r){ tr[v].value+=k*(r-l+1); tr[v].add+=k; return; } if(tr[v].add) spread(v); int mid=(tr[v].l+tr[v].r)>>1; if(r<=mid){ update(2*v,l,r,k); } else{ if(l>mid){ update(2*v+1,l,r,k); } else{ update(2*v,l,mid,k); update(2*v+1,mid+1,r,k); } } tr[v].value=tr[2*v].value+tr[2*v+1].value; } void query(int v,int l,int r){ //查询 if(tr[v].l==l&&tr[v].r==r){ ans+=tr[v].value; return; } if(tr[v].add) spread(v); int mid=(tr[v].l+tr[v].r)>>1; if(r<=mid){ query(2*v,l,r); } else{ if(l>mid){ query(2*v+1,l,r); } else{ query(2*v,l,mid); query(2*v+1,mid+1,r); } } tr[v].value=tr[2*v].value+tr[2*v+1].value; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%lld",&a[i]); build(1,1,n); while(m--){ int op; scanf("%d",&op); if(op==1){ int x,y; LL k; scanf("%d%d%lld",&x,&y,&k); update(1,x,y,k); } else{ int x,y; scanf("%d%d",&x,&y); ans=0; query(1,x,y); printf("%lld\n",ans); } } return 0; }
朋友们,无论这个世界变得怎样,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。