背景:今天心血来潮要重新码线段树。
但是。
突然发现真是一条不归路。
这出错那出错。
整了半天,发现两个小错误。
下面说说为什么重码。
之前写的在结构体中存了一个节点的L和R。
就比较费空间。
再加上码风难看和抄的题解,根本不可读。
所以重新写一遍。
代码如下(有lazy标记)。
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=100001; struct tree{ ll add,sum; }t[maxn<<2]; ll a[maxn]; int n,m; void build(int p,int l,int r){ if(l==r){ t[p].sum=a[l];return; } int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); t[p].sum=t[p<<1|1].sum+t[p<<1].sum; } inline void pushdown(int p,int l,int r){ if(!t[p].add) return; int mid=(l+r)>>1; t[p<<1].sum+=t[p].add*(mid-l+1); t[p<<1|1].sum+=t[p].add*(r-mid); t[p<<1].add+=t[p].add; t[p<<1|1].add+=t[p].add; t[p].add=0; } inline void ad(int p,int l,int r,int x,int y,int d){ if(x<=l && y>=r){ t[p].add+=d; t[p].sum+=(ll)d*(r-l+1); return; } pushdown(p,l,r); int mid=(l+r)>>1; if(x<=mid) ad(p<<1,l,mid,x,y,d); if(y>mid) ad(p<<1|1,mid+1,r,x,y,d); t[p].sum=t[p<<1].sum+t[p<<1|1].sum; } inline ll ask(int p,int l,int r,int x,int y){ if(x<=l && y>=r){ return t[p].sum; } pushdown(p,l,r); ll ans=0; int mid=(l+r)>>1; if(x<=mid) ans+=ask(p<<1,l,mid,x,y); if(y>mid) ans+=ask(p<<1|1,mid+1,r,x,y); return ans; } 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 c; scanf("%d",&c); if(c==1){ int x,y; ll k; scanf("%d%d%lld",&x,&y,&k); ad(1,1,n,x,y,k); } else{ int x,y; scanf("%d%d",&x,&y); printf("%lld ",ask(1,1,n,x,y)); } } // system("pause"); return 0; }
例题就是线段树1,luogu_P3372:https://www.luogu.org/problemnew/show/P3372