zoukankan      html  css  js  c++  java
  • [洛谷P3369] 普通平衡树 Treap & Splay

    这个就是存一下板子......

    题目传送门

    Treap的实现应该是比较正经的。

    插入删除前驱后继排名什么的都是平衡树的基本操作。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 using namespace std;
      6 
      7 int n,root,tot;
      8 
      9 struct treap
     10 {
     11     int ls,rs,v,rd,sz,h;
     12 }t[100005];
     13 
     14 void update(int p)
     15 {
     16     t[p].sz=t[t[p].ls].sz+t[t[p].rs].sz+t[p].h;
     17 }
     18 
     19 void zig(int &p)
     20 {
     21     int r=t[p].rs;
     22     t[p].rs=t[r].ls;
     23     t[r].ls=p;
     24     t[r].sz=t[p].sz;
     25     update(p);
     26     p=r;
     27 }
     28 
     29 void zag(int &p)
     30 {
     31     int l=t[p].ls;
     32     t[p].ls=t[l].rs;
     33     t[l].rs=p;
     34     t[l].sz=t[p].sz;
     35     update(p);
     36     p=l;
     37 }
     38 
     39 void insert(int &p,int val)
     40 {
     41     if(p==0)
     42     {
     43         tot++;
     44         p=tot;
     45         t[p].sz=t[p].h=1;
     46         t[p].v=val;
     47         t[p].rd=rand();
     48         return;
     49     }
     50     t[p].sz++;
     51     if(t[p].v==val)t[p].h++;
     52     else if(t[p].v<val)
     53     {
     54         insert(t[p].rs,val);
     55         if(t[p].rd>t[t[p].rs].rd)zig(p);
     56     }else
     57     {
     58         insert(t[p].ls,val);
     59         if(t[p].rd>t[t[p].ls].rd)zag(p);
     60     }
     61 }
     62 
     63 void del(int &p,int val)
     64 {
     65     if(!p)return;
     66     if(t[p].v==val)
     67     {
     68         if(t[p].h>1)
     69         {
     70             t[p].h--;
     71             t[p].sz--;
     72             return;
     73         }
     74         if(t[p].ls*t[p].rs==0)p=t[p].ls+t[p].rs;
     75         else if(t[t[p].ls].rd<t[t[p].rs].rd)
     76         {
     77             zag(p);
     78             del(p,val);
     79         }else
     80         {
     81             zig(p);
     82             del(p,val);
     83         }
     84     }else if(t[p].v<val)
     85     {
     86         t[p].sz--;
     87         del(t[p].rs,val);
     88     }else
     89     {
     90         t[p].sz--;
     91         del(t[p].ls,val);
     92     }
     93 }
     94 
     95 int qrank(int p,int val)
     96 {
     97     if(!p)return 0;
     98     if(t[p].v==val)return t[t[p].ls].sz+1;
     99     else if(t[p].v<val)return t[t[p].ls].sz+t[p].h+qrank(t[p].rs,val);
    100     else return qrank(t[p].ls,val);
    101 }
    102 
    103 int qnum(int p,int rk)
    104 {
    105     if(!p)return 0;
    106     int lsz=t[t[p].ls].sz+t[p].h;
    107     if(rk<=t[t[p].ls].sz)return qnum(t[p].ls,rk);
    108     else if(rk>lsz)return qnum(t[p].rs,rk-lsz);
    109     else return t[p].v;
    110 }
    111 
    112 void pre(int p,int val,int &ans)
    113 {
    114     if(!p)return;
    115     if(t[p].v<val)
    116     {
    117         ans=p;
    118         pre(t[p].rs,val,ans);
    119     }else pre(t[p].ls,val,ans);
    120 }
    121 
    122 void post(int p,int val,int &ans)
    123 {
    124     if(!p)return;
    125     if(t[p].v>val)
    126     {
    127         ans=p;
    128         post(t[p].ls,val,ans);
    129     }else post(t[p].rs,val,ans);
    130 }
    131 
    132 int main()
    133 {
    134     scanf("%d",&n);
    135     int op,x;
    136     while(n--)
    137     {
    138         scanf("%d%d",&op,&x);
    139         if(op==1)insert(root,x);
    140         if(op==2)del(root,x);
    141         if(op==3)printf("%d
    ",qrank(root,x));
    142         if(op==4)printf("%d
    ",qnum(root,x));
    143         if(op==5){int r=0;pre(root,x,r);printf("%d
    ",t[r].v);}
    144         if(op==6){int r=0;post(root,x,r);printf("%d
    ",t[r].v);}
    145     }
    146     return 0;
    147 }

    今天突然想用splay写一下,复习复习。

    之后发现第12个点T飞了......

    下载输入数据之后,发现这个数据是构造的,依次插入了1~50000这50000个数。

    用cfree调试了一下,发现这样会在splay上弄出一个长长的链。

    可能是我太菜了,但是我用了两种方法(具体见代码)都会出链导致T飞。

    最后为了男人的尊严,我用了一些玄学(随机)算法总算A掉了。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #define id(x) (s[f[x]][1]==x)
      6 using namespace std;
      7 
      8 int n,root=2,tot=2;
      9 int f[100005],s[100005][2];
     10 int v[100005],h[100005],sz[100005];
     11 
     12 void pushup(int p)
     13 {
     14     sz[p]=sz[s[p][0]]+sz[s[p][1]]+h[p];
     15 }
     16 
     17 void rotate(int p)
     18 {
     19     int k=id(p);
     20     int fa=f[p];
     21     s[fa][k]=s[p][!k];
     22     s[p][!k]=fa;
     23     s[f[fa]][id(fa)]=p;
     24     f[p]=f[fa];
     25     f[fa]=p;
     26     f[s[fa][k]]=fa;
     27     pushup(fa);
     28     pushup(p);
     29 }
     30 
     31 void splay(int p,int g)
     32 {
     33     while(f[p]!=g)
     34     {
     35         int fa=f[p];
     36         if(f[fa]==g)
     37         {
     38             rotate(p);
     39             break;
     40         }
     41         if(id(p)^id(fa))rotate(p);
     42         else rotate(fa);
     43         rotate(p);
     44     }
     45     if(!g)root=p;
     46 }
     47 
     48 void pre(int p,int val,int &ans)
     49 {
     50     if(!p)return;
     51     if(v[p]>=val)pre(s[p][0],val,ans);
     52     else ans=p,pre(s[p][1],val,ans);
     53 }
     54 
     55 void post(int p,int val,int &ans)
     56 {
     57     if(!p)return;
     58     if(v[p]<=val)post(s[p][1],val,ans);
     59     else ans=p,post(s[p][0],val,ans);
     60 }
     61 
     62 int qrank(int p,int num)
     63 {
     64     if(!p)return 0;
     65     if(num<v[p])return qrank(s[p][0],num);
     66     if(num==v[p])return sz[s[p][0]]+1;
     67     return sz[s[p][0]]+h[p]+qrank(s[p][1],num);
     68 }
     69 
     70 int qnum(int p,int rk)
     71 {
     72     if(!p)return 0;
     73     int lm=sz[s[p][0]]+h[p];
     74     if(rk<=sz[s[p][0]])return qnum(s[p][0],rk);
     75     if(rk>lm)return qnum(s[p][1],rk-lm);
     76     return v[p];
     77 }
     78 
     79 int d[100005];
     80 
     81 void ins(int val)
     82 {
     83     /*int bef,aft;
     84     pre(root,val,bef);
     85     post(root,val,aft);
     86     splay(bef,0);
     87     splay(aft,root);
     88     int gp=s[root][1];
     89     if(!s[gp][0])
     90     {
     91         s[gp][0]=++tot;
     92         f[tot]=gp;
     93         v[tot]=val;
     94     }
     95     h[s[gp][0]]++,sz[s[gp][0]]++;
     96     pushup(gp),pushup(root);*/
     97     
     98     int p=root,fa=0;
     99     while(p&&v[p]!=val)
    100     {
    101         fa=p;
    102         p=s[p][val>v[p]];
    103     }
    104     if(!p)
    105     {
    106         p=++tot;
    107         s[fa][val>v[fa]]=p;
    108         sz[p]=1;
    109         f[p]=fa;
    110         v[p]=val;
    111     }
    112     h[p]++;
    113     splay(p,0);
    114     int k=rand()%tot+1;
    115     while(d[k])k=rand()%tot+1;
    116     splay(k,0);
    117 }
    118 
    119 void del(int val)
    120 {
    121     int bef,aft;
    122     pre(root,val,bef);
    123     post(root,val,aft);
    124     splay(bef,0);
    125     splay(aft,root);
    126     int gp=s[root][1];
    127     h[s[gp][0]]--;
    128     sz[s[gp][0]]--;
    129     if(!h[s[gp][0]])d[s[gp][0]]=1,s[gp][0]=0;
    130     pushup(gp),pushup(root);
    131 }
    132 
    133 int main()
    134 {
    135     scanf("%d",&n);
    136     f[1]=2;
    137     s[2][0]=1;
    138     v[1]=-0x3f3f3f3f;
    139     v[2]=0x3f3f3f3f;
    140     h[1]=h[2]=sz[1]=1;
    141     sz[2]=2;
    142     for(int i=1;i<=n;i++)
    143     {
    144         int op,x;
    145         scanf("%d%d",&op,&x);
    146         if(op==1)ins(x);
    147         if(op==2)del(x);
    148         if(op==3){int rk=qrank(root,x)-1;printf("%d
    ",rk);}
    149         if(op==4){int num=qnum(root,x+1);printf("%d
    ",num);}
    150         if(op==5){int pos;pre(root,x,pos);printf("%d
    ",v[pos]);}
    151         if(op==6){int pos;post(root,x,pos);printf("%d
    ",v[pos]);}
    152     }
    153     return 0;
    154 }
  • 相关阅读:
    LeetCode(75) Sort Colors
    大众点评2015 在线笔试(1)
    百度2015 在线笔试题(3)
    百度2015 在线笔试题(2)
    百度2015 在线笔试题(1)
    其他 之网站分享插件
    Flask框架 之request对象
    Flask框架 之路由
    Flask框架 之第一个Flask程序
    微信 之网页授权登录
  • 原文地址:https://www.cnblogs.com/eternhope/p/9735305.html
Copyright © 2011-2022 走看看