Duan2baka的线段树模板!
2017-09-24 16:53
246 查看
区间加(Add_Seq),区间修改(Modify_Seq),区间求和(Query),区间最大值(Query_MAX),单点加(Add),单点修改(Modify)
有待补充…
有待补充…
#include<algorithm> #include<ctype.h> #include<cstdio> #define N 100050 using namespace std; inline int read(){ int x=0,f=1;char c=getchar(); while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();} while(isdigit(c)) x=(x<<3)+(x<<1)+c-'0',c=getchar(); return x*f; } int a ; struct Seg{ int l,r,sum,lazy,maxx,add; Seg *ls,*rs; }root; inline void Update(Seg *k){ if(k->ls==NULL) return; k->sum=k->ls->sum+k->rs->sum; k->maxx=max(k->ls->maxx,k->rs->maxx); } inline void Pushdown_MOD(Seg *k){ if(k->lazy==-1) return; if(k->ls!=NULL){ k->ls->lazy=k->lazy; k->ls->maxx=k->lazy; k->ls->sum=(k->ls->r-k->ls->l+1)*k->lazy; } if(k->rs!=NULL){ k->rs->lazy=k->lazy; k->rs->maxx=k->lazy; k->rs->sum=(k->rs->r-k->rs->l+1)*k->lazy; } k->lazy=-1; } inline void Pushdown_Add(Seg *k){ if(k->add==0) return; if(k->ls!=NULL){ k->ls->add+=k->add; k->ls->maxx+=k->add; k->ls->sum+=(k->ls->r-k->ls->l+1)*k->add; } if(k->rs!=NULL){ k->rs->add+=k->add; k->rs->maxx+=k->add; k->rs->sum+=(k->rs->r-k->rs->l+1)*k->add; } k->add=0; } inline void Pushdown(Seg *k){ Pushdown_MOD(k); Pushdown_Add(k); } void maketree(int l,int r,Seg *k){ k->l=l;k->r=r;k->add=0; if(l==r){ k->sum=0;k->maxx=0; return; } int mid=l+r>>1; k->ls=new(Seg);k->rs=new(Seg); maketree(l,mid,k->ls);maketree(mid+1,r,k->rs); Update(k); } void remake(Seg *k){ k->lazy=-1;k->add=0; if(k->l==k->r){ k->sum=k->maxx=a[k->l]; return; } remake(k->ls);remake(k->rs); Update(k); } void Delete(Seg *k){ if(k->ls!=NULL){ Delete(k->ls); } if(k->rs!=NULL){ Delete(k->rs); } delete(k); } void Add(int x,int v,Seg *k){ if(k->l==k->r){ k->sum+=v; return; } int mid=(k->l+k->r)>>1; if(x<=mid) Add(x,v,k->ls); else Add(x,v,k->rs); Update(k); } int Query(int x,int y,Seg *k){ if(x<=k->l && y>=k->r){ return k->sum; } int mid=(k->l+k->r)>>1,t; Pushdown(k);Update(k); if(y<=mid) t=Query(x,y,k->ls); else if(x>mid) t=Query(x,y,k->rs); else t=Query(x,y,k->ls)+Query(x,y,k->rs); Pushdown(k);Update(k); return t; } int Query_MAX(int x,int y,Seg *k){ if(x<=k->l && y>=k->r){ return k->maxx; } Pushdown(k); int mid=(k->l+k->r)>>1; if(y<=mid) return Query_MAX(x,y,k->ls); if(x>mid) return Query_MAX(x,y,k->rs); return max(Query_MAX(x,y,k->ls),Query_MAX(x,y,k->rs)); } void Modify(int x,int v,Seg *k){ if(k->l==k->r){ k->sum=v; k->maxx=v; return; } int mid=(k->l+k->r)>>1; if(x<=mid) Modify(x,v,k->ls); else Modify(x,v,k->rs); Update(k); } void Modify_Seq(int x,int y,int v,Seg *k){ if(k->l>=x && k->r<=y){ k->lazy=v; k->maxx=v;k->sum=(k->r-k->l+1)*v; return; } Pushdown(k); int mid=(k->l+k->r)>>1; if(y<=mid) Modify_Seq(x,y,v,k->ls); else if(x>mid) Modify_Seq(x,y,v,k->rs); else Modify_Seq(x,y,v,k->ls),Modify_Seq(x,y,v,k->rs); Update(k); } void Add_Seq(int x,int y,int v,Seg *k){ if(k->l>=x && k->r<=y){ k->add=k->add+v; k->maxx=k->maxx+v; k->sum=k->sum+(k->r-k->l+1)*v; return; } Pushdown(k);Update(k); int mid=(k->l+k->r)>>1; if(y<=mid) Add_Seq(x,y,v,k->ls); else if(x>mid) Add_Seq(x,y,v,k->rs); else Add_Seq(x,y,v,k->ls),Add_Seq(x,y,v,k->rs); Pushdown(k);Update(k); } main(){ return 0; }
相关文章推荐
- 【UVA】11992 - Fast Matrix Operations(线段树模板)
- (模板)线段树set(a,b) query(a,b)
- 玲珑杯1128--线段树模板
- 【HDU1540】【线段树】【区间合并】【一个PushUp合并还有下去的时候取区间】【可作为模板】
- 线段树模板
- [模板]-线段树-无Lazy
- 线段树求解区间最大最小值(模板)
- hdu1754(线段树单点替换&区间最值模板)
- Just a Hook HDU - 1698(线段树区间更换,区间询问模板)
- 算法模板——线段树
- poj2528&&线段树模板
- Duan2baka的Splay模板!(区间翻转)
- 洛谷 P3373 【模板】线段树 2 (线段树)
- 周中训练笔记——线段树模板(建树+更新)(9.7)
- HDU 2795 Billboard(线段树-水题,模板题)
- AHOI 2009 行星序列 BZOJ 1798 COGS 1272 线段树模板题:加、乘标记
- ACM_模板_线段树
- 线段树模板 区间加减 区间修改
- hdu 1754 I Hate It (模板线段树)
- cd 915E(离散化+线段树)(新线段树模板)