各种平衡树板子
Posted gxm123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种平衡树板子相关的知识,希望对你有一定的参考价值。
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 ",rk(x));break; 148 case 4: printf("%d ",rrk(x));break; 149 case 5: printf("%d ",lowe(x));break; 150 case 6: printf("%d ",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 ",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 ",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 ",rnk(x));break; 96 case 4:printf("%d ",tr[kth(rt,x)].val);break; 97 case 5:lower(x);break; 98 case 6:upper(x);break; 99 } 100 } 101 return 0; 102 }
以上是关于各种平衡树板子的主要内容,如果未能解决你的问题,请参考以下文章