• 各种平衡树


    记一下自己写的平衡树

    方便以后复制粘贴

    题目链接

    Vector

    最快:284ms

     1 #include<cstdio>
     2 #include<vector>
     3 #include<algorithm>
     4 using namespace std;
     5 const int MAXN=100005;
     6 vector<int>v;
     7 int n,opt,x;
     8 inline char nc()
     9 {
    10     static char buf[MAXN],*p1=buf,*p2=buf;
    11     return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
    12 }
    13 inline int read()
    14 {
    15     char c=nc();int x=0,f=1;
    16     while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
    17     while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
    18     return x*f;
    19 }
    20 int main()
    21 {
    22     v.reserve(100001);
    23     n=read();
    24     while(n--)
    25     {
    26         opt=read();x=read();
    27         if(opt==1)    v.insert(lower_bound(v.begin(),v.end(),x),x);
    28         if(opt==2)    v.erase (lower_bound(v.begin(),v.end(),x));
    29         if(opt==3)    printf("%d
    ",lower_bound(v.begin(),v.end(),x)-v.begin()+1);
    30         if(opt==4)    printf("%d
    ",v[x-1]);
    31         if(opt==5)    printf("%d
    ",v[lower_bound(v.begin(),v.end(),x)-v.begin()-1]);
    32         if(opt==6)    printf("%d
    ",v[upper_bound(v.begin(),v.end(),x)-v.begin()]);
    33     }
    34     return 0;
    35 }
    Vector

    Splay

    最快:128ms

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define ls(x) T[x].ch[0]
    #define rs(x) T[x].ch[1]
    #define fa(x) T[x].fa
    #define root T[0].ch[1]
    using namespace std;
    const int MAXN=1e5+10,mod=10007,INF=1e9+10;
    inline char nc()
    {
        static char buf[MAXN],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin)),p1==p2?EOF:*p1++;
    }
    inline int read()
    {
        char c=nc();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
        return x*f;
    }
    struct node
    {
        int fa,ch[2],val,rec,sum;
    }T[MAXN];
    int tot=0;
    void update(int x){T[x].sum=T[ls(x)].sum+T[rs(x)].sum+T[x].rec;}
    int ident(int x){return T[fa(x)].ch[0]==x?0:1;}
    void connect(int x,int fa,int how){T[fa].ch[how]=x;T[x].fa=fa;}
    void rotate(int x)
    {
        int Y=fa(x),R=fa(Y);
        int Yson=ident(x),Rson=ident(Y);
        connect(T[x].ch[Yson^1],Y,Yson);
        connect(Y,x,Yson^1);
        connect(x,R,Rson);
        update(Y);update(x);
    }
    void splay(int x,int to)
    {
        to=fa(to);
        while(fa(x)!=to)
        {
            int y=fa(x);
            if(T[y].fa==to) rotate(x);
            else if(ident(x)==ident(y)) rotate(y),rotate(x);
            else rotate(x),rotate(x);
        }
    }
    int newnode(int v,int f)
    {
        T[++tot].fa=f;
        T[tot].rec=T[tot].sum=1;
        T[tot].val=v;
        return tot;
    }
    void Insert(int x)
    {
        int now=root;
        if(root==0) {newnode(x,0);root=tot;}//
        else
        {
            while(1)
            {
                T[now].sum++;
                if(T[now].val==x) {T[now].rec++;splay(now,root);return ;}
                int nxt=x<T[now].val?0:1;
                if(!T[now].ch[nxt])
                {
                    int p=newnode(x,now);
                    T[now].ch[nxt]=p;
                    splay(p,root);return ;
                }
                now=T[now].ch[nxt];
            }        
        }
    }
    int find(int x)
    {
        int now=root;
        while(1)
        {
            if(!now) return 0;
            if(T[now].val==x) {splay(now,root);return now;}
            int nxt=x<T[now].val?0:1;
            now=T[now].ch[nxt];
        }
    }
    void delet(int x)
    {
        int pos=find(x);
        if(!pos) return ;
        if(T[pos].rec>1) {T[pos].rec--,T[pos].sum--;return ;} 
        else
        {
            if(!T[pos].ch[0]&&!T[pos].ch[1]) {root=0;return ;}
            else if(!T[pos].ch[0]) {root=T[pos].ch[1];T[root].fa=0;return ;}
            else
            {
                int left=T[pos].ch[0];
                while(T[left].ch[1]) left=T[left].ch[1];
                splay(left,T[pos].ch[0]);
                connect(T[pos].ch[1],left,1); 
                connect(left,0,1);//
                update(left);
            }
        }
    }
    int rak(int x)
    {
        int now=root,ans=0;
        while(1)
        {
            if(T[now].val==x) return ans+T[T[now].ch[0]].sum+1;
            int nxt=x<T[now].val?0:1;
            if(nxt==1) ans=ans+T[T[now].ch[0]].sum+T[now].rec;
            now=T[now].ch[nxt];
        }
    }
    int kth(int x)//排名为x的数 
    {
        int now=root;
        while(1)
        {
            int used=T[now].sum-T[T[now].ch[1]].sum;
            if(T[T[now].ch[0]].sum<x&&x<=used) {splay(now,root);return T[now].val;}
            if(x<used) now=T[now].ch[0];
            else now=T[now].ch[1],x-=used;
        }
    }
    int lower(int x)
    {
        int now=root,ans=-INF;
        while(now)
        {
            if(T[now].val<x) ans=max(ans,T[now].val);
            int nxt=x<=T[now].val?0:1;//这里需要特别注意 
            now=T[now].ch[nxt];
        }
        return ans;
    }
    int upper(int x)
    {
        int now=root,ans=INF;
        while(now)
        {
            if(T[now].val>x) ans=min(ans,T[now].val);
            int nxt=x<T[now].val?0:1;
            now=T[now].ch[nxt];
        }
        return ans;
    }
    int main()
    {
        #ifdef WIN32
        freopen("a.in","r",stdin);
        #else
        #endif
        int N=read();
        while(N--)
        {
            int opt=read(),x=read();
            if(opt==1) Insert(x);
            else if(opt==2) delet(x);
            else if(opt==3) printf("%d
    ",rak(x));
            else if(opt==4) printf("%d
    ",kth(x));
            else if(opt==5) printf("%d
    ",lower(x));
            else if(opt==6) printf("%d
    ",upper(x));
        } 
        return 0;
    }
    splay

    FHQ Treap

    最快:152ms

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<ctime>
    #include<cstdlib>
    using namespace std;
    #define ls T[now].ch[0]
    #define rs T[now].ch[1]
    const int MAXN=1e6+10;
    inline char nc()
    {
        static char buf[MAXN],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
    }
    inline int read()
    {
        char c=nc();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
        while(c>='0'&&c<='9'){x=x*10+c-'0',c=nc();}
        return x*f;
    }
    struct node
    {
        int ch[2],val,siz,pri;
    }T[MAXN];
    int tot=0;
    int x,y,z,root=0;
    int newnode(int v)
    {
        T[++tot].siz=1;
        T[tot].val=v;
        T[tot].pri=rand();
        return tot;
    }
    void update(int now)
    {
        T[now].siz=T[ls].siz+T[rs].siz+1;
    }
    void split(int now,int k,int &x,int &y)
    {
        if(!now)  {x=y=0;return ;} 
        if(T[now].val<=k)  x=now,split(rs,k,rs,y);
        else y=now,split(ls,k,x,ls);
        update(now);
    }
    int merge(int x,int y)
    {
        if(!x||!y)    return x+y;
        if(T[x].pri<T[y].pri)
        {
            T[x].ch[1]=merge(T[x].ch[1],y);
            update(x);
            return x;
        }
        else 
        {
            T[y].ch[0]=merge(x,T[y].ch[0]);
            update(y);
            return y;
        }
    }
    int kth(int now,int x)
    {
        while(1)
        {
            if(T[ls].siz>=x)     now=ls;
            else
                if(T[ls].siz+1==x)    return now;
                else     x-=T[ls].siz+1,now=rs;
        }
    }
    int main()
    {
        #ifdef WIN32
        freopen("a.in","r",stdin);
        #else
        #endif
        srand((unsigned)time(NULL));
        int n=read();
        while(n--)
        {
            int opt=read(),val=read();
            if(opt==1)
            {
                split(root,val,x,y);
                root=merge( merge(x,newnode(val)),y );
            }
            else if(opt==2)
            {
                split(root,val,x,z);
                split(x,val-1,x,y);
                y=merge(T[y].ch[0],T[y].ch[1]);
                root=merge( merge(x,y) ,z);
            }
            else if(opt==3)
            {
                split(root,val-1,x,y);
                printf("%d
    ",T[x].siz+1);
                root=merge(x,y);
            }
            else if(opt==4)
            {
                printf("%d
    ",T[kth(root,val)].val);
            }
            else if(opt==5)
            {
                split(root,val-1,x,y);
                printf("%d
    ",T[kth(x,T[x].siz)].val);
                root=merge(x,y);
            }
            else if(opt==6)
            {
                split(root,val,x,y);
                printf("%d
    ",T[kth(y,1)].val);
                root=merge(x,y);
            }
        }
        return 0;
    }
    FHQ Treap

    01 Trie树

    最快:84ms

     1 #include <cstdio>
     2 const int MAXN=1e6+10,INF=1e7;
     3 int ch[MAXN][2],num[MAXN],tot=2,root=1;
     4 inline char nc()
     5 {
     6     static char buf[MAXN],*p1=buf,*p2=buf;
     7     return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
     8 }
     9 inline int read()
    10 {
    11     char c=nc();int x=0,f=1;
    12     while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
    13     while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
    14     return x*f;
    15 }
    16 inline void insert(int x,int val)
    17 {
    18     x+=INF;
    19     for(int i=25,now=root,t; ~i; i--)
    20     {
    21         if( !(ch[now][ t=x>>i &1 ]) )    ch[now][t]=++tot;
    22         num[ now=ch[now][t] ]+=val;
    23     }
    24 }
    25 inline int rak(int x)
    26 {
    27     x+=INF;
    28     int ans=0;
    29     for(int i=25,now=root,t; ~i ; i--)
    30     {
    31         if( (t=x>>i &1) )    
    32             ans+=num[ ch[now][0] ];
    33         now=ch[now][t];
    34     }
    35     return ans;
    36 }
    37 inline int kth(int x)
    38 {
    39     int ans=0;
    40     for(int i=25,now=root; ~i ; i--)
    41     {
    42         if( x>num[ ch[now][0] ] )    ans|=1<<i,x-=num[ ch[now][0] ],now=ch[now][1];
    43         else now=ch[now][0];
    44     }
    45     return ans-INF;
    46 }
    47 int main() 
    48 {
    49     #ifdef WIN32
    50     freopen("a.in","r",stdin);
    51     #else
    52     #endif
    53     int n=read();
    54     while(n --) 
    55     {
    56         int x=read(),y=read();
    57         if(x==1) insert(y, 1);
    58         else if(x==2) insert(y, -1);
    59         else if(x==3) printf("%d
    ", rak(y) + 1);
    60         else if(x==4) printf("%d
    ", kth(y) );
    61         else if(x==5) printf("%d
    ", kth( rak(y) ) );
    62         else if(x==6) printf("%d
    ", kth( rak(y + 1) + 1) );
    63     }
    64 }
    01 Trie树

    Treap

    最快:88ms

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #define ls tree[k].l
      5 #define rs tree[k].r
      6 using namespace std;
      7 const int MAXN=1e6+10;
      8 inline char nc()
      9 {
     10     static char buf[MAXN],*p1=buf,*p2=buf;
     11     return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin))?EOF:*p1++;
     12 }
     13 inline int read()
     14 {
     15     char c=nc();int x=0,f=1;
     16     while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
     17     while(c>='0'&&c<='9'){x=x*10+c-'0',c=nc();}
     18     return x*f;
     19 }
     20 struct node
     21 {
     22     int l,r,tot,recy,val,rd;
     23 }tree[MAXN];
     24 int size,root,ans=0;
     25 inline void update(int k)
     26 {
     27    tree[k].tot=tree[ls].tot+tree[rs].tot+tree[k].recy;
     28 }
     29 inline void insert(int &k,int x)
     30 {
     31     if(k==0)
     32     {
     33         ++size;k=size;
     34         tree[size].recy=tree[size].tot=1;
     35         tree[size].val=x;tree[size].rd=rand();return ;
     36     }
     37     tree[k].tot++;
     38     if(tree[k].val==x)    tree[k].recy++;
     39     else if(x < tree[k].val)    insert( ls, x);
     40     else insert( rs , x );
     41 }
     42 inline void LeftRotate(int &k)
     43 {
     44     int R=tree[k].r;
     45     tree[k].r=tree[R].l;
     46     tree[R].l=k;
     47     tree[R].tot=tree[k].tot;
     48     update(k);k=R;
     49 }
     50 inline void RightRotate(int &k)
     51 {
     52     int R=tree[k].l;
     53     tree[k].l=tree[R].r;
     54     tree[R].r=k;
     55     tree[R].tot=tree[k].tot;
     56     update(k);k=R;
     57 }
     58 inline void del(int &k,int x)
     59 {
     60     if(!k)    return ;
     61     if(tree[k].val==x)
     62     {
     63         if(tree[k].recy>1)    {tree[k].recy-=1,tree[k].tot-=1;return; }
     64         if(tree[k].l*tree[k].r==0)    k=tree[k].l+tree[k].r;
     65         else if(tree[ls].rd<tree[rs].rd)    RightRotate(k),del(k,x);
     66         else LeftRotate(k),del(k,x);
     67     }
     68     else if(x>tree[k].val)    tree[k].tot--,del(rs,x);
     69     else tree[k].tot--,del(ls,x);
     70 }
     71 int atrank(int &k,int x)
     72 {
     73     if(k==0)    return 0;
     74     if(tree[k].val==x)    return tree[ls].tot+1;
     75     if(tree[k].val<x)    return atrank(rs,x)+tree[ls].tot+tree[k].recy;
     76     else return atrank(ls,x);
     77 }
     78 int rerand(int k,int x)
     79 {
     80     if(k==0)    return 0;
     81     if(x<=tree[ls].tot)    return rerand(ls,x);
     82     else if(x>tree[ls].tot+tree[k].recy)    return rerand(rs,x-tree[ls].tot-tree[k].recy);
     83     else return tree[k].val;
     84 }
     85 void pred(int k,int x)
     86 {
     87     if(k==0) return ;
     88     if(tree[k].val<x)    ans=k,pred(rs,x);
     89     else pred(ls,x);
     90 }
     91 void succ(int &k,int x)
     92 {
     93     if(k==0) return ;
     94     if(tree[k].val>x)    ans=k,succ(ls,x);
     95     else succ(rs,x);
     96 }
     97 int main()
     98 {
     99     #ifdef WIN32
    100     freopen("a.in","r",stdin);
    101     #else
    102     #endif
    103     int n=read();
    104     while(n--)
    105     {
    106         int opt=read(),x=read();ans=0;
    107         if(opt==1)  insert(root,x);
    108         if(opt==2)  del(root,x);
    109         if(opt==3)  printf("%d
    ",atrank(root,x));
    110         if(opt==4)  printf("%d
    ",rerand(root,x));
    111         if(opt==5)  {pred(root,x);printf("%d
    ",tree[ans].val);}
    112         if(opt==6)  {succ(root,x);printf("%d
    ",tree[ans].val);}
    113     }
    114 }
    Treap
  • 相关阅读:
    对象接口
    final关键字
    面向对象----多态,抽象,接口
    面向对象中的继承、封装、构造与析构函数
    PHP类与对象
    JS项目
    AppStore IAP 客户端校验代码
    Android线程计时器实现
    Cocos2d-x java 通过jni调用c++的方法
    ios7 uuid的获取方法
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/7953516.html
Copyright © 2020-2023  润新知