zoukankan      html  css  js  c++  java
  • 平衡树学习笔记

    学了一个星期才学会了三个平衡树……吃枣药丸

    SBT到时候再补坑吧……红黑树和AVL就算了

    话说那个$o(lglgn)$的VeB树是真的厉害

    注:以下都是以BZOJ3224普通平衡树为模板

    Splay

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    struct Splay{
        struct node{
                int v,fa,son[2],siz,sum;
            //0:左儿子 1:右儿子
        }t[200001];
        int tot,rt;
        Splay(){
            tot=rt=0;
        }
        void newnode(int val){
            t[++tot].v=val;
            t[tot].fa=t[tot].son[0]=t[tot].son[1]=0;
            t[tot].sum=t[tot].siz=1;
        }
        void clear(int x){
            t[x].v=t[x].fa=t[x].son[0]=t[x].son[1]=t[x].sum=t[x].siz=0;
        }
        int lr(int x){
            return t[t[x].fa].son[1]==x;
        }
        void update(int x){
            if(x){
                t[x].siz=t[x].sum;
                if(t[x].son[0])t[x].siz+=t[t[x].son[0]].siz;
                if(t[x].son[1])t[x].siz+=t[t[x].son[1]].siz;
            }
        }
        void rotate(int x){
            int p=t[x].fa,pp=t[p].fa,ch=lr(x);
            t[p].son[ch]=t[x].son[ch^1];
            t[t[p].son[ch]].fa=p;
            t[p].fa=x;
            t[x].son[ch^1]=p;
            t[x].fa=pp;
            if(pp)t[pp].son[t[pp].son[1]==p]=x;
            update(p);
            update(x);
        }
        void splay(int x,int p){
            for(int f;(f=t[x].fa)!=p;rotate(x)){
                if(t[f].fa!=p)rotate(lr(x)==lr(f)?f:x);
            }
            if(!p)rt=x;
        }
        void insert(int x){
            if(rt==0){
                newnode(x);
                rt=tot;
                return;
            }
            int now=rt,f=0;
            for(;;){
                if(t[now].v==x){
                    t[now].sum++;
                    update(now);
                    update(f);
                    splay(now,0);
                    return;
                }
                f=now;
                now=t[now].son[t[now].v<x];
                if(!now){
                    newnode(x);
                    t[tot].fa=f;
                    t[f].son[t[f].v<x]=tot;
                    update(f);
                    splay(tot,0);
                    return;
                }
            }
        }
        int pre(){
            int now=t[rt].son[0];
            while(t[now].son[1])now=t[now].son[1];
            return now;
        }
        int nxt(){
            int now=t[rt].son[1];
            while(t[now].son[0])now=t[now].son[0];
            return now;
        }
        int find(int x){
            int ans=0,now=rt;
            for(;;){
                if(x<t[now].v)now=t[now].son[0];
                else{
                    ans+=(t[now].son[0]?t[t[now].son[0]].siz:0);
                    if(x==t[now].v){
                        splay(now,0);
                        return ans+1;
                    }
                    ans+=t[now].sum;
                    now=t[now].son[1];
                }
            }
        }
        int findx(int x){
            int now=rt;
            for(;;){
                if(t[now].son[0]&&x<=t[t[now].son[0]].siz)now=t[now].son[0];
                else{
                    int tmp=(t[now].son[0]?t[t[now].son[0]].siz:0)+t[now].sum;
                    if(x<=tmp)return t[now].v;
                    x-=tmp;
                    now=t[now].son[1];
                }
            }
        }
        void del(int x){
            int kk=find(x);
            if(t[rt].sum>1){
                t[rt].sum--;
                return;
            }
            if(!t[rt].son[0]&&!t[rt].son[1]){
                clear(rt);
                rt=0;
                return;
            }
            if(!t[rt].son[1]){
                int rrt=rt;
                rt=t[rrt].son[0];
                t[rt].fa=0;
                clear(rrt);
                return;
            }
            if(!t[rt].son[0]){
                int rrt=rt;
                rt=t[rrt].son[1];
                t[rt].fa=0;
                clear(rrt);
                return;
            }
            int pr=pre(),rrt=rt;
            splay(pr,0);
            t[t[rrt].son[1]].fa=rt;
            t[rt].son[1]=t[rrt].son[1];
            clear(rrt);
            update(rt);
        }
        int ppre(int x){
            insert(x);
            int ans=t[pre()].v;
            del(x);
            return ans;
        }
        int nnxt(int x){
            insert(x);
            int ans=t[nxt()].v;
            del(x);
            return ans;
        }
    }splaytree;
    int n,op,x;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&op,&x);
            switch(op){
                case 1:splaytree.insert(x);break;
                case 2:splaytree.del(x);break;
                case 3:printf("%d
    ",splaytree.find(x));break;
                case 4:printf("%d
    ",splaytree.findx(x));break;
                case 5:printf("%d
    ",splaytree.ppre(x));break;
                case 6:printf("%d
    ",splaytree.nnxt(x));break;
            }
        } 
        return 0;
    }

    Treap(旋转版)

      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<ctime>
      7 using namespace std;
      8 struct Treap{
      9     struct node{
     10         int v,son[2],siz,k,sum;
     11     }t[1000001];
     12     int MAX_RAND,tot,rt;
     13     Treap(){
     14         srand(time(NULL));
     15         MAX_RAND=138138138;
     16         tot=rt=0;
     17     }
     18     int rd(){
     19         return rand()%MAX_RAND;
     20     }
     21     void newnode(int val){
     22         t[++tot].v=val;
     23         t[tot].k=rd();
     24         t[tot].son[0]=t[tot].son[1]=0;
     25         t[tot].siz=t[tot].sum=1;
     26     }
     27     void update(int x){
     28         t[x].siz=t[t[x].son[0]].siz+t[t[x].son[1]].siz+t[x].sum;
     29     }
     30     void rotate(int &x,int ch){
     31         //ch=0:左;ch=1:右; 
     32         int s=t[x].son[ch^1];
     33         t[x].son[ch^1]=t[s].son[ch];
     34         t[s].son[ch]=x;
     35         update(x);
     36         update(x=s);
     37     }
     38     void insert(int &x,int v){
     39         if(!x){
     40             newnode(v);
     41             x=tot;
     42             return;
     43         }
     44         if(t[x].v==v){
     45             t[x].sum++;
     46             t[x].siz++;
     47             return;
     48         }
     49         int ch=t[x].v<v;
     50         insert(t[x].son[ch],v);
     51         t[x].siz++;
     52         if(t[t[x].son[ch]].k<t[x].k)rotate(x,ch^1);
     53     }
     54     bool del(int &x,int p){
     55         if(!x)return false;
     56         if(t[x].v==p){
     57             if(t[x].sum>1){
     58                 t[x].siz--;
     59                 t[x].sum--;
     60                 return true;
     61             }else if(!t[x].son[0]||!t[x].son[1]){
     62                 x=t[x].son[0]?t[x].son[0]:t[x].son[1];
     63                 return true;
     64             }else{
     65                 rotate(x,t[t[x].son[0]].k<t[t[x].son[1]].k);
     66                 del(x,p);
     67             }
     68         }else{
     69             if(!del(t[x].son[t[x].v<p],p))return false;
     70             t[x].siz--;
     71             return true;
     72         }
     73     }
     74     int find(int x){
     75         int u=rt,ans=1;
     76         while(u){
     77             if(x<t[u].v)u=t[u].son[0];
     78             else if(x>t[u].v){
     79                 ans+=t[t[u].son[0]].siz+t[u].sum;
     80                 u=t[u].son[1];
     81             }else return ans+t[t[u].son[0]].siz;
     82         }
     83     }
     84     int findx(int x){
     85         int u=rt;
     86         while(u){
     87             if(x<=t[t[u].son[0]].siz)u=t[u].son[0];
     88             else if(x>t[t[u].son[0]].siz+t[u].sum){
     89                 x-=t[t[u].son[0]].siz+t[u].sum;
     90                 u=t[u].son[1];
     91             }else return t[u].v;
     92         }
     93     }
     94     int pre(int x){
     95         int u=rt,ans;
     96         while(u){
     97             if(t[u].v<x){
     98                 ans=t[u].v;
     99                 u=t[u].son[1];
    100             }else u=t[u].son[0];
    101         }
    102         return ans;
    103     }
    104     int nxt(int x){
    105         int u=rt,ans;
    106         while(u){
    107             if(t[u].v>x){
    108                 ans=t[u].v;
    109                 u=t[u].son[0];
    110             }else u=t[u].son[1];
    111         }
    112         return ans;
    113     }
    114 }treap;
    115 int n,op,x; 
    116 int main(){
    117     scanf("%d",&n);
    118     for(int i=1;i<=n;i++){
    119         scanf("%d%d",&op,&x);
    120         switch(op){
    121             case 1:treap.insert(treap.rt,x);break;
    122             case 2:treap.del(treap.rt,x);break;
    123             case 3:printf("%d
    ",treap.find(x));break;
    124             case 4:printf("%d
    ",treap.findx(x));break;
    125             case 5:printf("%d
    ",treap.pre(x));break;
    126             case 6:printf("%d
    ",treap.nxt(x));break;
    127         }
    128     } 
    129     return 0;
    130 }

    替罪羊树

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #define inf 233333333
      6 using namespace std;
      7 const double alpha=0.75;
      8 struct ScapegoatTree{    
      9     struct node{
     10         int s,son[2],fa,siz,sum;
     11     }t[500001];
     12     int rt,tot,cnt,s[200001];
     13     ScapegoatTree(){
     14         rt=1;
     15         cnt=2;
     16         t[1].sum=-inf;
     17         t[1].siz=2;
     18         t[1].son[1]=2;
     19         t[2].sum=inf;
     20         t[2].siz=1;
     21         t[2].fa=1;
     22         memset(s,0,sizeof(s));
     23     }
     24     bool check(int u){
     25         return (double)t[u].siz*alpha>=(double)t[t[u].son[0]].siz &&
     26         (double)t[u].siz*alpha>=(double)t[t[u].son[1]].siz;
     27     }
     28     void rec(int u){//把树压扁 
     29         if(t[u].son[0])rec(t[u].son[0]);
     30         s[++tot]=u;
     31         if(t[u].son[1])rec(t[u].son[1]);
     32     }
     33     int build(int l,int r){
     34         if(l>r)return 0;
     35         int mid=(l+r)/2,k=s[mid];
     36         t[k].son[0]=build(l,mid-1);
     37         t[k].son[1]=build(mid+1,r);
     38         t[t[k].son[0]].fa=k;
     39         t[t[k].son[1]].fa=k;
     40         t[k].siz=t[t[k].son[0]].siz+t[t[k].son[1]].siz+1;
     41         return k;
     42     }
     43     void rebuild(int u){
     44         tot=0;
     45         rec(u);
     46         int f=t[u].fa,sn=(t[t[u].fa].son[1]==u),now=build(1,tot);
     47         t[f].son[sn]=now,t[t[f].son[sn]].fa=f;
     48         if(u==rt)rt=now;
     49     }
     50     void ins(int x){
     51         int now=rt;
     52         t[++cnt].siz=1;
     53         t[cnt].sum=x;
     54         for(;;){
     55             t[now].siz++;
     56             bool sn=(x>=t[now].sum);
     57             if(t[now].son[sn])now=(t[now].son[sn]);
     58             else{
     59                 t[now].son[sn]=cnt;
     60                 t[cnt].fa=now;
     61                 break;
     62             }
     63         }
     64         int rb=0;
     65         for(int i=cnt;i;i=t[i].fa)if(!check(i))rb=i;
     66         if(rb)rebuild(rb);
     67     }
     68     int get(int x){
     69         int now=rt;
     70         for(;;){
     71             if(t[now].sum==x)return now;
     72             else now=t[now].son[x>t[now].sum];
     73         }
     74     }
     75     int pre(int u){
     76         int now=t[u].son[0];
     77         while(t[now].son[1])now=t[now].son[1];
     78         return now;
     79     }
     80     int nxt(int u){
     81         int now=t[u].son[1];
     82         while(t[u].son[0])now=t[now].son[0];
     83         return now;
     84     }
     85     void del(int x){
     86         int u=get(x);
     87         if(t[u].son[0]&&t[u].son[1]){
     88             int nt=pre(u);
     89             t[u].sum=t[nt].sum;
     90             u=nt;
     91         }
     92         int sn=(t[u].son[0])?t[u].son[0]:t[u].son[1],snn=t[t[u].fa].son[1]==u;;
     93         t[t[u].fa].son[snn]=sn;
     94         t[sn].fa=t[u].fa;
     95         for(int i=t[u].fa;i;i=t[i].fa)t[i].siz--;
     96         if(u==rt)rt=sn;
     97     }
     98     int find(int x){
     99         int now=rt,ret=0;
    100         while(now){
    101             if(t[now].sum<x){
    102                 ret+=t[t[now].son[0]].siz+1;
    103                 now=t[now].son[1];
    104             }else now=t[now].son[0];
    105         }
    106         return ret;
    107     }
    108     int findx(int x){
    109         int now=rt;
    110         for(;;){
    111             if(t[t[now].son[0]].siz==x-1)return t[now].sum;
    112             else if(t[t[now].son[0]].siz>=x)now=t[now].son[0];
    113             else x-=t[t[now].son[0]].siz+1,now=t[now].son[1];
    114         }
    115     }
    116     int ppre(int x){
    117         int now=rt,ret=-inf;
    118         while(now){
    119             if(t[now].sum<x)ret=max(ret,t[now].sum),now=t[now].son[1];
    120             else now=t[now].son[0];
    121         }
    122         return ret;
    123     }
    124     int nnxt(int x){
    125         int now=rt,ret=inf;
    126         while(now){
    127             if(t[now].sum>x)ret=min(ret,t[now].sum),now=t[now].son[0];
    128             else now=t[now].son[1];
    129         }
    130         return ret;
    131     }
    132 }scg;
    133 int n,op,x;
    134 int main(){
    135     scanf("%d",&n);
    136     for(int i=1;i<=n;i++){
    137         scanf("%d%d",&op,&x);
    138         switch(op){
    139             case 1:scg.ins(x);break;
    140             case 2:scg.del(x);break;
    141             case 3:printf("%d
    ",scg.find(x));break;
    142             case 4:printf("%d
    ",scg.findx(x+1));break;
    143             case 5:printf("%d
    ",scg.ppre(x));break;
    144             case 6:printf("%d
    ",scg.nnxt(x));break;
    145         } 
    146     }
    147     return 0;
    148 }

    Size Balanced Tree

    待填坑~~~

    小测试:

    xsy评测Splay133ms,Treap95ms,替罪羊树89ms(Alpha=0.75)

    所以说替罪羊树才是最优秀的平衡树!(然而区间操作就萎了)

  • 相关阅读:
    正式班D25
    解决oracle用户锁定
    python学习第17天
    python学习第16天
    python学习第15天
    python学习第十四天
    python学习第13天
    Python基础
    python学习第12天
    python学习第11天
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/9222756.html
Copyright © 2011-2022 走看看