线段树模板
2017-03-04 22:50
225 查看
自己写的模板,方便以后查看
求最大值的:
求区间和:
区间更新的:
求最大值的:
#include<iostream> #include<cstdio> using namespace std; #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 const int maxn=222222; int value[maxn<<2]; void PushUp(int rt) { value[rt]=max(value[rt<<1],value[rt<<1|1]); } void btree(int l,int r,int rt) { //初始为(1,n,1) if(l==r) { scanf("%d",&value[rt]); return ; } int m=(l+r)>>1; btree(ls); btree(rs); PushUp(rt); } void update(int x,int v,int l,int r,int rt) { //初始化为(a,b,1,n,1) if(l==r) { value[rt]=v; return ; } int m=(l+r)>>1; if(x<=m)update(x,v,ls); else update(x,v,rs); PushUp(rt); } int query(int L,int R,int l,int r,int rt) { //初始化为(a,b,1,n,1) if(L<=l&&r<=R)return value[rt]; int m=(l+r)>>1,ans=0; if(L<=m)ans=max(ans,query(L,R,ls)); if(R>m)ans=max(ans,query(L,R,rs)); return ans; } int main() { }
求区间和:
#include<iostream> #include<cstdio> using namespace std; #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 const int maxn=50005; int value[maxn<<2],ans; void PushUp(int rt) { value[rt]=value[rt<<1]+value[rt<<1|1]; } void btree(int l,int r,int rt) { //初始为(1,n,1) if(l==r) { scanf("%d",&value[rt]); return ; } int m=(l+r)>>1; btree(ls); btree(rs); PushUp(rt); } void update(int x,int v,int l,int r,int rt) { //初始化为(a,b,1,n,1) if(l==r) { value[rt]+=v; return ; } int m=(l+r)>>1; if(x<=m)update(x,v,ls); else update(x,v,rs); PushUp(rt); } void query(int L,int R,int l,int r,int rt) { //初始化为(a,b,1,n,1) if(L<=l&&r<=R) { ans+=value[rt]; return ; } if(l==r)return; int m=(l+r)>>1; if(R<=m)query(L,R,ls); else if(L>m)query(L,R,rs); else { query(L,R,ls); query(L,R,rs); } } int main() { return 0; }
区间更新的:
#include<iostream> #include<cstdio> using namespace std; #define ll long long #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 const int maxn=100005; ll value[maxn<<2],add[maxn<<2]; void PushUp(int rt) { value[rt]=value[rt<<1]+value[rt<<1|1]; } void PushDown(int rt,int m)//m是当前节点区间的范围 { //例如1-5 右儿子4-5,左儿子1-3 m=5,m>>1=2刚好是右儿子区间范围,m-(m>>1)=3为左儿子区间范围 if(add[rt])//向下更新子节点 { add[rt<<1]+=add[rt];//更新左儿子的lazy标记 add[rt<<1|1]+=add[rt];//右儿子 value[rt<<1]+=(m-(m>>1))*add[rt];//更新左儿子的权值,应该乘上左儿子区间(r-l+1) value[rt<<1|1]+=(m>>1)*add[rt];//应该乘右儿子区间范围 add[rt]=0; } } void btree(int l,int r,int rt) { //初始化1,n,1 add[rt]=0; if(l==r) { scanf("%lld",&value[rt]); return ; } int m=(l+r)>>1; btree(ls); btree(rs); PushUp(rt); } void update(int L,int R,int c,int l,int r,int rt) { //初始化a,b,c,1,n,1 if(L<=l&&r<=R)//给定区间大于现有区间 { add[rt]+=c;//标记加上 value[rt]+=(ll)c*(r-l+1);//更新当前节点 return ; } PushDown(rt,r-l+1);//向下更新子节点因为下一步要使用子节点 int m=(l+r)>>1; if(L<=m)update(L,R,c,ls); if(R>m)update(L,R,c,rs); PushUp(rt);//向上关系父节点 } ll query(int L,int R,int l,int r,int rt) { //初始化为a,b,1,n,1 if(L<=l&&r<=R)return value[rt]; PushDown(rt,r-l+1); int m=(l+r)>>1; ll ans=0; if(L<=m)ans+=query(L,R,ls); if(R>m)ans+=query(L,R,rs); return ans; } int main() { }
相关文章推荐
- 线段树模板(最简便)
- 线段树模板及其详细解释
- 线段树知识点理解及其模板代码
- 线段树,不带延迟的模板
- 【模板】线段树
- 线段树,小模板
- HDU 1754 线段树模板
- 洛谷P3372 【模板】线段树 1
- 线段树区间更新,区间求和,最大值,最小值模板
- leetcode@ [307] Range Sum Query - Mutable / 线段树模板
- 线段树(模板)
- 【常用模板】 线段树单点操作
- HDU 1166 线段树模板&树状数组模板
- H - Just a Hook (线段树模板)
- Codeforces 46 D Parking Lot(线段树区间更新模板题)
- 洛谷P3372 线段树1【模板】
- 线段树练习 3&P3372 【模板】线段树 1
- 线段树(递归)模板
- 线段树模板
- 2017 icpc 南宁赛区 F.Overlapping Rectangles(重叠矩形的最大面积+线段树模板)