码迷,mamicode.com
首页 > 其他好文 > 详细

各种平衡树板子

时间:2020-03-05 21:00:30      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:split   upper   connect   namespace   cas   find   merge   inf   treap   

Splay

  1 #include <cstdio>
  2 #include <iostream>
  3 using namespace std;
  4 const int maxn=1e5+5,inf=0x3f3f3f3f;
  5 int siz[maxn],fa[maxn],ch[maxn][2],rep[maxn],vl[maxn];
  6 int n,tot;
  7 
  8 inline int ids(int x) {return ch[fa[x]][0]==x?0:1;}
  9 
 10 inline void update(int x) {siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+rep[x];}
 11 
 12 inline void connect(int x,int f,int fs) {fa[x]=f;ch[f][fs]=x;}
 13 
 14 inline void rotate(const int &x)
 15 {
 16     int f=fa[x],ff=fa[fa[x]];
 17     int s1=ids(x),s2=ids(f);
 18     connect(ch[x][s1^1],f,s1);connect(f,x,s1^1);connect(x,ff,s2);
 19     update(f);update(x);
 20 }
 21 
 22 inline void splay(int x,int to)
 23 {
 24     while(fa[x]!=to)
 25     {
 26         if(fa[fa[x]]==to) rotate(x);
 27         else if(ids(fa[x])==ids(x)) rotate(fa[x]),rotate(x);
 28         else rotate(x),rotate(x);
 29     }
 30 }
 31 
 32 inline int cre(const int &val,const int &f) {fa[++n]=f;vl[n]=val;siz[n]=rep[n]=1;return n;}
 33 
 34 int find(int val)
 35 {
 36     int now=ch[0][0],nxt;
 37     while(1)
 38     {
 39         if(vl[now]==val){
 40             splay(now,0);
 41             return now;
 42         }
 43         nxt=val<vl[now]?0:1;
 44         if(!ch[now][nxt]) return 0;
 45         now=ch[now][nxt];
 46     }
 47 }
 48 
 49 void insert(int val)
 50 {
 51     tot++;
 52     if(!ch[0][0]) {ch[0][0]=cre(val,0);return;}
 53     int now=ch[0][0],nxt;
 54     while(1)
 55     {
 56         siz[now]++;
 57         if(val==vl[now]){
 58             rep[now]++;splay(now,0);return;
 59         }
 60         nxt=val<vl[now]?0:1;
 61         if(!ch[now][nxt])
 62         {
 63             ch[now][nxt]=cre(val,now);
 64             splay(ch[now][nxt],0);
 65             return;
 66         }
 67         now=ch[now][nxt];
 68     }
 69 }
 70 
 71 inline int lowe(int x)
 72 {
 73     int now=ch[0][0],ans=-inf;
 74     while(now){
 75         if(vl[now]<x&&vl[now]>ans) ans=vl[now];
 76         now=ch[now][x>vl[now]?1:0];
 77     }
 78     return ans;
 79 }
 80 
 81 inline int uppe(int x)
 82 {
 83     int now=ch[0][0],ans=inf;
 84     while(now){
 85         if(vl[now]>x&&vl[now]<ans) ans=vl[now];
 86         now=ch[now][x<vl[now]?0:1];
 87     }
 88     return ans;
 89 }
 90 
 91 void delt(int x)
 92 {
 93     tot--;
 94     int dl=find(x);
 95     if(!dl) return;
 96     if(rep[dl]>1) {siz[dl]--;rep[dl]--;return;}
 97     if(!ch[dl][0]) {connect(ch[dl][1],0,0);return;}
 98     if(!ch[dl][1]) {connect(ch[dl][0],0,0);return;}
 99     int px=ch[dl][0];
100     while(ch[px][1]) px=ch[px][1];
101     splay(px,dl);
102     connect(ch[dl][1],px,1);connect(px,0,0);
103     update(px);
104 }
105 
106 int rk(int val)
107 {
108     int ans=0,now=ch[0][0];
109     while(now)
110     {
111         if(vl[now]==val){
112             ans+=siz[ch[now][0]]+1;break;
113         }
114         if(val<vl[now]) now=ch[now][0];
115         else ans+=siz[ch[now][0]]+rep[now],now=ch[now][1];
116     }
117     splay(now,0);
118     return ans;
119 }
120 
121 int rrk(int x)
122 {
123     if(x>tot) return -inf;
124     int now=ch[0][0],tmp;
125     while(now)
126     {
127         tmp=rep[now]+siz[ch[now][0]];
128         if(siz[ch[now][0]]<x&&x<=tmp) break;
129         if(x<tmp) now=ch[now][0];
130         else x-=tmp,now=ch[now][1];
131     }
132     splay(now,0);
133     return vl[now];
134 }
135 
136 int main()
137 {
138     int t,opt,x;
139     scanf("%d",&t);
140     for(int i=1;i<=t;i++)
141     {
142         scanf("%d%d",&opt,&x);
143         switch(opt)
144         {
145             case 1: insert(x);break;
146             case 2: delt(x);break;
147             case 3: printf("%d\n",rk(x));break;
148             case 4: printf("%d\n",rrk(x));break;
149             case 5: printf("%d\n",lowe(x));break;
150             case 6: printf("%d\n",uppe(x));break;
151             default: break;
152         }
153     }
154     return 0;
155 }

Fhq-treap

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <ctime>
  4 #include <cstdlib>
  5 using namespace std;
  6 const int maxn=1e5+5;
  7 struct Fhq_treep_Node
  8 {
  9     int val,siz,ch[2],rnd;
 10 }tr[maxn];
 11 int rt,r1,r2,r3,utot;
 12 
 13 inline void update(const int &u) {tr[u].siz=tr[tr[u].ch[0]].siz+tr[tr[u].ch[1]].siz+1;}
 14 inline int newnode(const int &val) {tr[++utot].val=val;tr[utot].siz=1;tr[utot].rnd=rand();return utot;}
 15 
 16 void split(int u,int val,int &a,int &b)
 17 {
 18     if(!u) {a=b=0;return;}
 19     if(tr[u].val<=val) a=u,split(tr[a].ch[1],val,tr[a].ch[1],b);
 20     else b=u,split(tr[b].ch[0],val,a,tr[b].ch[0]);
 21     update(u);
 22 }
 23 
 24 int merge(int a,int b)
 25 {
 26     if(!a||!b) return a+b;
 27     if(tr[a].rnd<tr[b].rnd){
 28         tr[a].ch[1]=merge(tr[a].ch[1],b);
 29         update(a);return a;
 30     }
 31     else{
 32         tr[b].ch[0]=merge(a,tr[b].ch[0]);
 33         update(b);return b;
 34     }
 35 }
 36 
 37 void insert(int val)
 38 {
 39     split(rt,val,r1,r2);
 40     rt=merge(r1,merge(newnode(val),r2));
 41 }
 42 
 43 void delt(int val)
 44 {
 45     split(rt,val,r1,r3);
 46     split(r1,val-1,r1,r2);
 47     r2=merge(tr[r2].ch[0],tr[r2].ch[1]);
 48     rt=merge(merge(r1,r2),r3);
 49 }
 50 
 51 int rnk(int val)
 52 {
 53     split(rt,val-1,r1,r2);
 54     int ans=tr[r1].siz+1;
 55     rt=merge(r1,r2);
 56     return ans;
 57 }
 58 
 59 int kth(int u,int k)
 60 {
 61     while(1)
 62     {
 63         if(tr[tr[u].ch[0]].siz>=k) u=tr[u].ch[0];
 64         else if(k>tr[tr[u].ch[0]].siz+1) k=k-tr[tr[u].ch[0]].siz-1,u=tr[u].ch[1];
 65         else return u;
 66     }
 67 }
 68 
 69 void lower(int val)
 70 {
 71     split(rt,val-1,r1,r2);
 72     printf("%d\n",tr[kth(r1,tr[r1].siz)].val);
 73     rt=merge(r1,r2);
 74 }
 75 
 76 void upper(int val)
 77 {
 78     split(rt,val,r1,r2);
 79     printf("%d\n",tr[kth(r2,1)].val);
 80     rt=merge(r1,r2);
 81 }
 82 
 83 int main()
 84 {
 85     srand(time(0));
 86     int opt,x,t;
 87     scanf("%d",&t);
 88     while(t--)
 89     {
 90         scanf("%d%d",&opt,&x);
 91         switch(opt)
 92         {
 93             case 1:insert(x);break;
 94             case 2:delt(x);break;
 95             case 3:printf("%d\n",rnk(x));break;
 96             case 4:printf("%d\n",tr[kth(rt,x)].val);break;
 97             case 5:lower(x);break;
 98             case 6:upper(x);break;
 99         }
100     }
101     return 0;
102 }

 

各种平衡树板子

标签:split   upper   connect   namespace   cas   find   merge   inf   treap   

原文地址:https://www.cnblogs.com/gxm123/p/12422416.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!