zoukankan      html  css  js  c++  java
  • [普通平衡树splay]【学习笔记】

    参考:

    http://blog.csdn.net/clove_unique/article/details/50630280

    gty课件

    找一个好的风格太难了,自己习惯用struct,就强行用struct写了一下数组版的,同时加了些宏简化代码

    都是迭代写法

    splay要维护fa指向父亲

    rotate是把x转到fa,要更新f和x

    splay是把x转到tar的孩子,x成为root就是tar=0,注意更新root

    ins考虑空树,考虑已经存在,插入新节点的话要保留last到最后处理父亲,然后做splay

    (递归写法的传引用已经解决了设置祖先的问题)

    del

    先找要删除的,splay到根

    1.多个直接--

    2.空树直接root=0

    3.只有一个儿子,令独生子变成根,删去该点。
    4.左右儿子都有。找到左子树中权值最大的点,将其 splay 到左儿子的位置。然后将 整棵右子树挂在左儿子的右边。删除节点。 

    其他操作差不多了

    ps:比treap慢了一倍

    //
    //  main.cpp
    //  splay
    //
    //  Created by Candy on 27/11/2016.
    //  Copyright © 2016 Candy. All rights reserved.
    //
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define pa t[x].fa
    #define lc t[x].ch[0]
    #define rc t[x].ch[1]
    const int N=2e5+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    struct node{
        int fa,ch[2],v,w,size;
    }t[N];
    int cnt,root;
    inline int wh(int x){return t[pa].ch[1]==x;}
    inline void update(int x){t[x].size=t[lc].size+t[rc].size+t[x].w;}
    inline void rotate(int x){//x-->pa
        int f=t[x].fa,g=t[f].fa,c=wh(x);
        if(g) t[g].ch[wh(f)]=x;
        t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f;
        t[x].ch[c^1]=f;t[f].fa=x;
        t[x].fa=g;
        update(f);update(x);
    }
    inline void splay(int x,int tar){//x-->x.fa==tar
        for(;t[x].fa!=tar;rotate(x))
            if(t[pa].fa!=tar) rotate(wh(x)==wh(pa)?pa:x);
        if(tar==0) root=x;
    }
    
    inline int nw(int v){
        cnt++;
        t[cnt].v=v;t[cnt].ch[0]=t[cnt].ch[1]=t[cnt].fa=0;
        t[cnt].w=t[cnt].size=1;
        return cnt;
    }
    inline void ins(int v){
        if(root==0){root=nw(v);return;}//empty tree
        int x=root,last=0;
        while(x!=0){
            if(t[x].v==v){t[x].w++;t[x].size++;splay(x,0);return;}
            last=x;
            if(v<t[x].v) x=lc; else x=rc;
        }
        int tmp=nw(v);
        if(v<t[last].v) t[last].ch[0]=tmp;
        else t[last].ch[1]=tmp;
        t[tmp].fa=last;update(last);//no need for ancient because splay()
        splay(tmp,0);
    }
    inline int find(int v){
        int x=root;
        while(x!=0){
            if(v==t[x].v) break;
            if(v<t[x].v) x=lc;
            else x=rc;
        }
        if(x!=0) splay(x,0);
        return x;
    }
    inline int pre(){
        int x=t[root].ch[0];
        while(rc) x=rc;
        return x;
    }
    inline void del(int v){
        int x=find(v);
        if(t[x].w>1) {t[x].w--,t[x].size--;return;}
        if(lc==0&&rc==0) root=0;
        else if(rc==0) t[lc].fa=0,root=lc;
        else if(lc==0) t[rc].fa=0,root=rc;
        else{
            int tmp=t[root].ch[0];
            while(t[tmp].ch[1]) tmp=t[tmp].ch[1];
            splay(tmp,x);
            t[tmp].ch[1]=rc;t[rc].fa=tmp;
            t[tmp].fa=0;
            root=tmp;
            update(root);
        }
    }
    inline int rnk(int v){
        int x=root,ls=0;
        while(x!=0){
            if(t[x].v==v){
                int ans=ls+t[lc].size+1;
                splay(x,0);
                return ans;
            }
            if(v<t[x].v) x=lc;
            else ls+=t[lc].size+t[x].w,x=rc;
        }
        return -1;
    }
    inline int kth(int k){
        int x=root,ls=0;
        while(x!=0){
            int tmp=ls+t[lc].size;
            if(tmp+1<=k&&k<=tmp+t[x].w){
                splay(x,0);return t[x].v;
            }
            if(k<=tmp) x=lc;
            else ls=tmp+t[x].w,x=rc;
        }
        return -1;
    }
    inline int pre(int v){
        int ans=0,x=root;
        while(x!=0){
            if(t[x].v<v) ans=x,x=rc;
            else x=lc;
        }
        return ans;
    }
    inline int suf(int v){
        int ans=0,x=root;
        while(x!=0){//printf("suf %d %d
    ",x,t[x].v);
            if(v<t[x].v) ans=x,x=lc;
            else x=rc;
        }
        return ans;
    }
    int n,op,x,ans;
    int main(int argc, const char * argv[]){
        n=read();
        while(n--){
            op=read();x=read();
            switch(op){
                case 1:ins(x);break;
                case 2:del(x);break;
                case 3:printf("%d
    ",rnk(x));break;
                case 4:printf("%d
    ",kth(x));break;
                case 5:ans=pre(x);printf("%d
    ",t[ans].v);break;
                case 6:ans=suf(x);printf("%d
    ",t[ans].v);break;
            }
        }
        return 0;
    }
    View Code

    [2016-11-30]

    复习了一遍

    注意:

    find和ins操作要splay,有的地方直接return的话忘记splay了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define pa t[x].fa
    #define lc t[x].ch[0]
    #define rc t[x].ch[1]
    const int N=2e5+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    struct node{
        int fa,ch[2],w,size,v;
    }t[N];
    int cnt,root;
    inline void update(int x){t[x].size=t[lc].size+t[rc].size+t[x].w;}
    inline int wh(int x){return t[pa].ch[1]==x;}
    inline void rotate(int x){
        int f=t[x].fa,g=t[f].fa,c=wh(x);
        if(g) t[g].ch[wh(f)]=x;t[x].fa=g;
        t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f;
        t[x].ch[c^1]=f;t[f].fa=x;
        update(f);update(x);
    }
    inline void splay(int x,int tar){
        for(;t[x].fa!=tar;rotate(x))
            if(t[pa].fa!=tar) rotate(wh(pa)==wh(x)?pa:x);
        if(tar==0) root=x;
    }
    inline int nw(int v){
        cnt++;
        t[cnt].ch[0]=t[cnt].ch[1]=t[cnt].fa=0;
        t[cnt].w=t[cnt].size=1;t[cnt].v=v;
        return cnt;
    }
    void ins(int v){
        if(root==0){root=nw(v);return;}
        int x=root,last=0;
        while(x){
            if(t[x].v==v){t[x].w++;t[x].size++;splay(x,0);return;}
            last=x;
            if(v<t[x].v) x=lc;else x=rc;
        }
        int _=nw(v);
        if(v<t[last].v) t[last].ch[0]=_;
        else t[last].ch[1]=_;
        t[_].fa=last;
        splay(_,0);
    }
    int find(int v){
        int x=root;
        while(x){
            if(t[x].v==v) break;//not return cause splay
            if(v<t[x].v) x=lc;else x=rc;
        }
        if(x!=0) splay(x,0);
        return x;
    }
    void del(int v){
        int x=find(v);
        if(t[x].w>1){t[x].w--;t[x].size--;return;}
        if(lc==0&&rc==0) root=0;
        else if(rc==0) t[lc].fa=0,root=lc;
        else if(lc==0) t[rc].fa=0,root=rc;
        else{
            int _=lc;
            while(t[_].ch[1]) _=t[_].ch[1];
            splay(_,x);
            t[_].ch[1]=rc;t[rc].fa=_;
            t[_].fa=0;root=_;
            update(root);
        }
    }
    int rnk(int v){
        int x=root,ls=0;
        while(x){
            if(t[x].v==v){
                int ans=ls+t[lc].size+1;
                splay(x,0);
                return ans;
            }
            if(v<t[x].v) x=lc;else ls+=t[lc].size+t[x].w,x=rc;
        }
        return -1;
    }
    int kth(int k){
        int x=root,ls=0;
        while(x){
            int _=ls+t[lc].size;
            if(_<k&&k<=_+t[x].w) return t[x].v;
            if(k<=_) x=lc;
            else ls=_+t[x].w,x=rc;
        }
        return -1;
    }
    int pre(int v){
        int x=root,ans=0;
        while(x){
            if(v>t[x].v) ans=x,x=rc;
            else x=lc;
        }
        return ans;
    }
    int suf(int v){
        int x=root,ans=0;
        while(x){
            if(v<t[x].v) ans=x,x=lc;
            else x=rc;
        }
        return ans;
    }
    int n,op,x,ans;
    int main(int argc, const char * argv[]){
        n=read();
        while(n--){
            op=read();x=read();
            switch(op){
                case 1:ins(x);break;
                case 2:del(x);break;
                case 3:printf("%d
    ",rnk(x));break;
                case 4:printf("%d
    ",kth(x));break;
                case 5:ans=pre(x);printf("%d
    ",t[ans].v);break;
                case 6:ans=suf(x);printf("%d
    ",t[ans].v);break;
            }
        }
        return 0;
    }
  • 相关阅读:
    验证一下spark Row getAS类型以及控制问题
    Spark异常处理有时间好好拜读一下,spark拍错好文章
    Hive SQL 报错
    Objenesis类库学习一下,没有符合的构造器也可以创建对象
    Scala可变参数方法或者函数传参问题
    大数据相关英文博客,感觉还不错。Mark一下http://dwgeek.com/
    Tomcat 7 'javax.el.ELException' 的解决方式(failed to parse the expression [${xxx}])
    The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar
    在Tomcat中进行数据池连接是所需的包
    EL表达式
  • 原文地址:https://www.cnblogs.com/candy99/p/6109099.html
Copyright © 2011-2022 走看看