平衡树学习笔记

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

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\n",splaytree.find(x));break;
            case 4:printf("%d\n",splaytree.findx(x));break;
            case 5:printf("%d\n",splaytree.ppre(x));break;
            case 6:printf("%d\n",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\n",treap.find(x));break;
124             case 4:printf("%d\n",treap.findx(x));break;
125             case 5:printf("%d\n",treap.pre(x));break;
126             case 6:printf("%d\n",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\n",scg.find(x));break;
142             case 4:printf("%d\n",scg.findx(x+1));break;
143             case 5:printf("%d\n",scg.ppre(x));break;
144             case 6:printf("%d\n",scg.nnxt(x));break;
145         } 
146     }
147     return 0;
148 }

Size Balanced Tree

待填坑~~~

小测试:

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

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

posted @ 2018-06-25 09:18  DCDCBigBig  阅读(239)  评论(0编辑  收藏  举报