线段树学习总结

来源:互联网 发布: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);    }}// 网上都有详解
原创粉丝点击