线段树学习总结
来源:互联网 发布:tplink访客网络是什么 编辑:程序博客网 时间:2024/06/06 18:35
队伍分好后,我负责数据结构部分。。。。 以后要狂补数据结构了,不能再做水题找存在感了。
今天总结一下线段树 以后长期更新题型。。
**
part 1 线段树是是什么?
**
线段树是一种可以方便维护数列的数据结构。 更新和查找都可以在log(n)的复杂度内完成。 经(我)证(不)明(会)其最差空间复杂度为4*n。记住就好。
线段树可以看做维护线段的树
part 2 线段树如何的结构是什么?
首先,线段树可以看做一颗完全二叉树
完全二叉树有什么用呢? 我们发(百)现(度) 二叉树符合二进制思想,我们可以从一开始从上往下 从左至右编号 如下图
这就很完美,我们可以在log(n)的时间内查找到我们想要查找的任意一个点。
**
part 3 线段树如何建立?
**
下面给出一个看(比)得(较)懂(长)的模板。
线段树的建立 build() 函数
#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define fuck(x) cout<<x<<endl#define mem(a,b) memset(a,b,sizeof a)using namespace std;const int MAX=55555;int n;void pushup(int rt){ sum[rt]=(sum[rt<<1|1]+sum[rt<<1|1]); // 递归后把子节点的信息传给父节点}void build(int l,int r,int rt){ sum[rt]=xxxx;// 初始化节点 // 以下为固定代码 if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson); pushup(rt);}
区间更新pushdown函数,用于区间更新 add数组为懒惰标记数组
//以下代码为区间加减代码void pushdown(int rt){ if(add[rt]!=-1) { sum[rt<<1|1]+=add[rt]; sum[rt<<1]+=add[rt]; add[rt<<1|1]+=add[rt]; add[rt<<1]+=add[rt]; add[rt]=-1; }}
涉及区间合并 求最长区间或符合条件的连续区间一般这么写
class node{public: int llen,rlen,tlen;}; // 我们将sum数组由int型换成自定义类 //llen表示该节点所代表区间以左端开始最长合法区间 //rlen为该节点所代表的区间以右端结束的最长合法区间//tlen为该区间里最长合法区间。
node sum[MAX<<2];int a[MAX];void pushup(int l,int r,int rt){ int m=(l+r)>>1; sum[rt].tlen=max(max(sum[rt<<1].tlen,sum[rt<<1|1].tlen),sum[rt<<1|1].llen+sum[rt<<1].rlen); sum[rt].llen=sum[rt<<1].llen; if(sum[rt].llen==(m-l+1)) sum[rt].llen+=sum[rt<<1|1].llen; sum[rt].rlen=sum[rt<<1|1].rlen; if(sum[rt].rlen==(r-m)) sum[rt].rlen+=sum[rt<<1].rlen;}void build(int l,int r,int rt){ sum[rt].llen=sum[rt].rlen=sum[rt].tlen=(r-l+1); if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); pushup(l,r,rt);}void update(int p,bool flag,int l,int r,int rt){ if(l==r) { sum[rt].llen=sum[rt].rlen=sum[rt].tlen=flag; return; } int m=(l+r)>>1; if(p>m) update(p,flag,rson); else if(p<=m) update(p,flag,lson); pushup(l,r,rt);}int ans=-1;int query(int p,int l,int r,int rt){ if(l==r) return ans=sum[rt].tlen; int m=(l+r)>>1; if(p<=m) { if(m-sum[rt<<1].rlen<=p) return query(p,lson)+sum[rt<<1|1].llen; else return query(p,lson); } else { if(m+sum[rt<<1|1].llen>=p) return query(p,rson)+sum[rt<<1].rlen; else return query(p,rson); }}// 网上都有详解
阅读全文
0 0
- 线段树学习总结
- 【原创】 线段树学习总结
- 有关学习线段树很好的总结
- 线段树总结
- 简单线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树 总结
- 线段树总结
- 线段树最后总结
- E
- vue + webpack 安装和配置
- 13.12—动态规划—Word Break
- 考研英语
- [VC.NET]句柄
- 线段树学习总结
- 倒角距离匹配
- Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)
- 1029. 旧键盘(20)
- 历经漫长的跟踪、排查、对比、推动和验证, 终于在8个月后,解决了这个bug
- 15.1—细节实现题—Reverse Integer
- 大型信息系统中基础平台设计
- iOS事件的传递和响应
- pssh(1)