• 几种平衡树


      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #define ls(x) (x->ch[0])
      5 #define rs(x) (x->ch[1])
      6 #define sz(x) (x->size)
      7 #define p(x) (x->p)
      8 using namespace std;
      9 const int INF=0x7fffffff;
     10 struct son
     11 {
     12     int v,size;
     13     son *ch[2],*p;
     14     son(int x)
     15     {
     16         v=x;size=1;
     17     }
     18 };
     19 son *root,*null;
     20 son* newson(int val)
     21 {
     22     son *x=new son(val);
     23     ls(x)=rs(x)=p(x)=null;
     24     return x;
     25 }
     26 void pushup(son *x){sz(x)=sz(ls(x))+sz(rs(x))+1;}
     27 int rank(int val)
     28 {
     29     son *x=root;
     30     int ans=0;
     31     while(x!=null)
     32     {
     33         if(val>x->v){ans+=(sz(ls(x))+1);x=rs(x);}
     34         else x=ls(x);
     35     }
     36     return ans;
     37 }
     38 son* kth(int k)
     39 {
     40     //printf("sha bi qin shi yu
    ");
     41     son *x=root;
     42     while(x!=null)
     43     {
     44         if(sz(ls(x))+1==k)return x;
     45         if(sz(ls(x))+1>k)x=ls(x);
     46         else {k-=(sz(ls(x))+1);x=rs(x);}
     47     }
     48     return null;
     49 }
     50 int islc(son *x){return ls(p(x))==x;}
     51 // is left child ???
     52 //x在右,就左旋  在左,就右旋 
     53 void rot(son *x,int d)
     54 {
     55     son *y=x->ch[d^1];
     56     if(p(x)!=null)p(x)->ch[islc(x)^1]=y;//祖父儿子=y
     57     else root=y;
     58     p(y)=p(x);//把祖父儿子设成y 
     59     x->ch[d^1]=y->ch[d];//
     60     if(y->ch[d])p(y->ch[d])=x;//把y的d同向儿子改成x的d逆向儿子 
     61     y->ch[d]=x;p(x)=y;//把x的爸爸改成y 
     62     pushup(x);pushup(y); 
     63 }
     64 void splay(son *x,son *t=null)//把x旋到以t为祖父节点 
     65 {
     66     for(son *rt=p(x);rt!=t;rt=p(x))
     67     {
     68         if(p(rt)==t)
     69         {
     70             rot(rt,islc(x));
     71             return ;
     72         }
     73         if(islc(x)==islc(rt))rot(p(rt),islc(rt));//一字型旋转 第一步 
     74         else rot(rt,islc(x));//之字形旋转 第一步 
     75         rot(p(x),islc(x));//第二步 (此时x已经转上去)
     76     }
     77 }
     78 void add(int val)
     79 {
     80     int pos=rank(val);//val排名-1 
     81     splay(kth(pos));//把前一个转到root
     82     splay(kth(pos+1),root);//把pos+1的转到root右儿子
     83     //val 卡在pos和pos+1之间 
     84     son *x=newson(val);
     85     root->ch[1]->ch[0]=x;
     86     p(x)=root->ch[1];
     87     pushup(root->ch[1]);pushup(root);
     88 }
     89 void del(int val)
     90 {
     91     int pos=rank(val)+1;
     92     splay(kth(pos-1));splay(kth(pos+1),root);
     93     //把val卡在pos-1和pos+1之间
     94     root->ch[1]->ch[0]=null;
     95     pushup(root->ch[1]);pushup(root);
     96 }
     97 int n;
     98 
     99 int main(){
    100     //freopen("phs.in","r",stdin);
    101     //freopen("phs.out","w",stdout);
    102     null=new son(0);sz(null)=0;
    103     root=newson(-INF);
    104     root->ch[1]=newson(INF);//即把一开始的区间调成-INF到INF
    105     p(root->ch[1])=root; 
    106     scanf("%d",&n);
    107     for(int i=1;i<=n;++i)
    108     {
    109         int opt,x;scanf("%d%d",&opt,&x);
    110         switch(opt)
    111         {
    112             case 1:add(x);break;
    113             case 2:del(x);break;
    114             case 3:printf("%d
    ",rank(x));break;
    115             //返回值就是rank的原因:********
    116             //一开始root的值=-INF root右儿子=INF *******
    117             //每次查找一定会到这两个节点,而他们size=1 
    118             case 4:printf("%d
    ",kth(x+1)->v);break;
    119             //不能轻易在rank上+1,必须在x上+1 
    120             case 5:printf("%d
    ",kth(rank(x))->v);break;
    121             case 6:printf("%d
    ",kth(rank(x+1)+1)->v);break;
    122         }
    123     }
    124     while(1);
    125     return 0;
    126 }
    Splay详细注释
      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define ls(x) (x->l)
      6 #define rs(x) (x->r)
      7 #define sz(x) ((x)?(x->size):(0))
      8 using namespace std;
      9 struct Treap
     10 {
     11     struct treap
     12     {
     13         int size,fix,val;
     14         treap *l,*r;
     15         treap(int x)
     16         {
     17             val=x;fix=rand();size=1;
     18             l=r=NULL;
     19         }
     20     }*root;
     21     void pushup(treap *x){x->size=sz(ls(x))+sz(rs(x))+1;}
     22     void lturn(treap *&x)
     23     {
     24         treap *y=rs(x);
     25         rs(x)=ls(y);pushup(x);
     26         ls(y)=x;pushup(y);
     27         x=y;
     28     }
     29     void rturn(treap *&x)
     30     {
     31         treap *y=ls(x);
     32         ls(x)=rs(y);pushup(x);
     33         rs(y)=x;pushup(y);
     34         x=y;
     35     }
     36     void add(treap *&x,int val)
     37     {
     38         if(x==NULL)
     39         {
     40             x=new treap(val);
     41             return ;
     42         }
     43         if(val<x->val)
     44         {
     45             add(ls(x),val);
     46             pushup(x);
     47             if(ls(x)->fix>x->fix)rturn(x);
     48         }
     49         else
     50         {
     51             add(rs(x),val);
     52             pushup(x);
     53             if(rs(x)->fix>x->fix)lturn(x);
     54         }
     55     }
     56     void del(treap *&x,int val)
     57     {
     58         if(val==x->val)
     59         {
     60             if(ls(x)&&rs(x))
     61             {
     62                 if(ls(x)->fix>rs(x)->fix){rturn(x);del(rs(x),val);}
     63                 else {lturn(x);del(ls(x),val);}
     64             }
     65             else
     66             {
     67                 treap *y=NULL;
     68                 if(ls(x))y=ls(x);
     69                 else y=rs(x);
     70                 delete x;x=y;
     71             }
     72         }
     73         else
     74         {
     75             if(val<x->val)del(ls(x),val);
     76             else del(rs(x),val);
     77         }
     78         if(x)pushup(x);
     79     }
     80     int rank(int val)
     81     {
     82         treap *x=root;
     83         int ans=0;
     84         while(x)
     85         {
     86             if(val>x->val){ans+=(sz(ls(x))+1);x=rs(x);}
     87             else x=ls(x);
     88         }
     89         return ans;
     90     }
     91     treap* kth(int k)
     92     {
     93         treap *x=root;
     94         while(x)
     95         {
     96             int size=sz(ls(x))+1;
     97             if(size==k)return x;
     98             if(size>=k)x=ls(x);
     99             // = 向右走,因为add的时候就是向右 
    100             else {k-=size;x=rs(x);}
    101         }
    102     }
    103 }T;
    104 
    105 int m,u,o;
    106 
    107 int main(){
    108     //freopen("phs.in","r",stdin);
    109     //freopen("phs.out","w",stdout);
    110     scanf("%d",&m);
    111     while(m--)
    112     {
    113         scanf("%d%d",&u,&o);
    114         if(u==1)T.add(T.root,o);
    115         else if(u==2)T.del(T.root,o);
    116         else if(u==3)printf("%d
    ",T.rank(o)+1);
    117         else if(u==4)printf("%d
    ",T.kth(o)->val);
    118         else if(u==5)printf("%d
    ",T.kth(T.rank(o))->val);
    119         else printf("%d
    ",T.kth(T.rank(o+1)+1)->val);
    120         //加2有可能返回一个空指针,炸掉你 
    121     }
    122     while(1);
    123     return 0;
    124 }
    旋转Treap
  • 相关阅读:
    w3c盒子模型与ie盒子模型
    前端入门
    连接数据库好用工具
    前端开发工具
    刚发现的取色工具
    使用val()另一个妙用------选中select/checkbox/radio的值
    z-index的妙用
    react生命周期函数
    react中虚拟dom的diff算法
    React中的虚拟DOM
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7278798.html
Copyright © 2020-2023  润新知