【模板】bzoj-3224普通平衡树(splay&treap&SBT)
2018-01-03 22:29
603 查看
先吐槽一下,要找块好模板真不容易,毕竟大家都有各自的代码风格,强迫自己去看非自己风格的代码真是痛苦,所以在网上添加一种类型的模板
最近才发现这题A了三遍,分别是以三种平衡树的模板题A的,所以稍微汇总一下,让后来者有个类型的模板可以依靠
相信看模板的人都看过题解了,所以这里就不写题解了 本来就是模板题,哪来的题解
如果有刚学平衡树的,奉劝一句
splay好好学,SBT慢慢学,treap仔细学
最近才发现这题A了三遍,分别是以三种平衡树的模板题A的,所以稍微汇总一下,让后来者有个类型的模板可以依靠
相信看模板的人都看过题解了,所以这里就不写题解了 本来就是模板题,哪来的题解
如果有刚学平衡树的,奉劝一句
splay好好学,SBT慢慢学,treap仔细学
splaysplay 版:
#include<bits/stdc++.h> using namespace std; #define update(x) tr[x].size=tr[tr[x].ch[0]].size+tr[tr[x].ch[1]].size+tr[x].cnt #define cl(x) memset(x,0,sizeof(x)) #define cl1(x) memset(x,-1,sizeof(x)) #define rg register #define oo 0x3f3f3f3f template <typename _Tp> inline void read(_Tp&x){char c11=getchar();x=0;bool booo=0; while(c11!='-'&&!isdigit(c11))c11=getchar();if(c11=='-')c11=getchar(),booo=1; while(isdigit(c11)){x=x*10+c11-'0';c11=getchar();}if(booo)x=-x;return ; } const int N=505000; struct node{int size,f,ch[2],val,cnt;}tr ; int root,sz; inline int nxt(int,int); inline void find(int); inline void insert(int); inline void del(int); inline int K_th(int); inline void rotate(int x){ int fa=tr[x].f; int grand=tr[fa].f; int le=(tr[fa].ch[1]==x); tr[grand].ch[tr[grand].ch[1]==fa]=x; tr[x].f=grand; tr[fa].ch[le]=tr[x].ch[le^1]; tr[tr[x].ch[le^1]].f=fa; tr[x].ch[le^1]=fa; tr[fa].f=x; update(fa);update(x); return ; } void splay(int x,int target){ for(rg int fa;(fa=f[x])!=target;rotate(x)) if(f[f[x]]!=target) rotate(blood(x)==blood(f[x])?f[x]:x); if(!target)root=x; return ; } int main(){ insert(-oo);insert(+oo); rg int m,opt,A;read(m); while(m--){ read(opt);read(A); switch(opt){ case 1: insert(A); break; case 2: del(A); break; case 3: find(A); printf("%d\n",tr[tr[root].ch[0]].size); break; case 4: printf("%d\n",K_th(A+1)); break; case 5: printf("%d\n",tr[nxt(A,0)].val); break; case 6: printf("%d\n",tr[nxt(A,1)].val); break; default: puts("ERROR"); return 0; } } return 0; } inline int K_th(int x){ int now=root; if(tr[now].size<x)return -1; while("KB is too powerful"){ if(x>tr[tr[now].ch[0]].size+tr[now].cnt){ x-=tr[tr[now].ch[0]].size+tr[now].cnt; now=tr[now].ch[1]; } else if(x<=tr[tr[now].ch[0]].size) now=tr[now].ch[0]; else return tr[now].val; } return -1; } inline void del(int x){ int fr=nxt(x,0),Ba=nxt(x,1); splay(fr,0);splay(Ba,fr); if(tr[tr[Ba].ch[0]].cnt>1){ --tr[tr[Ba].ch[0]].cnt; splay(tr[Ba].ch[0],0); } else tr[Ba].ch[0]=0; return ; } inline void insert(int x){ int now=root,f=0; while(now&&tr[now].val!=x){ f=now; now=tr[now].ch[x>tr[now].val]; } if(now)++tr[now].cnt; else{ now=++sz; if(f)tr[f].ch[x>tr[f].val]=now; tr[now].ch[0]=tr[now].ch[1]=0; tr[now].f=f,tr[now].val=x; tr[now].cnt=1;tr[now].size=1; } splay(now,0); return ; } inline int nxt(int x,int leaf){ find(x); int now=root; if(leaf&&tr[now].val>x)return now; if(!leaf&&tr[now].val<x)return now; now=tr[now].ch[leaf]; while(tr[now].ch[leaf^1])now=tr[now].ch[leaf^1]; return now; } inline void find(int x){ if(!root)return ; int now=root; while(tr[now].ch[x>tr[now].val]&&x!=tr[now].val)now=tr[now].ch[x>tr[now].val]; splay(now,0); return ; }
treaptreap 版:
//bzoj3224 #include<bits/stdc++.h> using namespace std; #define rg register #define update(x) size[now]=size[ch[now][0]]+size[ch[now][1]]+tot[now]; template <typename _Tp> inline void read(_Tp&x){ char c11=getchar();x=0;bool booo=0; while(c11!='-'&&!isdigit(c11))c11=getchar();if(c11=='-'){c11=getchar();booo=1;} while(isdigit(c11)){x=x*10+c11-'0';c11=getchar();}if(booo)x=-x;return ; } const int N=100005; int ch [2],data ,rnd ,tot ,size ; int n,root,ans,sz; inline void lturn(int &now){ int child=ch[now][1];ch[now][1]=ch[child][0];ch[child][0]=now; size[child]=size[now];update(now);now=child; return ; } inline void rturn(int &now){ int child=ch[now][0];ch[now][0]=ch[child][1];ch[child][1]=now; size[child]=size[now];update(now);now=child; return ; } void ins(int &now,int x){ if(!now){ now=++sz; size[now]=tot[now]=1; data[now]=x;rnd[now]=rand(); return ; } ++size[now]; if(data[now]==x){++tot[now];return ;} if(data[now]<x){ ins(ch[now][1],x); if(rnd[ch[now][1]]<rnd[now])lturn(now); } else{ ins(ch[now][0],x); if(rnd[ch[now][0]]<rnd[now])rturn(now); } return ; } void del(int &now,int x){ if(!now)return ; if(data[now]==x){ if(tot[now]>1){--tot[now],--size[now];return ;} if(!(ch[now][0]*ch[now][1])){now=ch[now][0]+ch[now][1];return ;} if(rnd[ch[now][0]]<rnd[ch[now][1]]) rturn(now),del(now,x); else lturn(now),del(now,x); return ; } --size[now]; if(data[now]<x) del(ch[now][1],x); else del(ch[now][0],x); return ; } int get_rank(int x){ int now=root,basic=0; while(1){ if(!now)break; if(data[now]==x){basic+=size[ch[now][0]]+1;break;} if(x<data[now])now=ch[now][0]; else basic+=size[ch[now][0]]+tot[now],now=ch[now][1]; } return basic; } int get_num(int x){ int now=root; while(1){ if(!now)return 0; if(x<=size[ch[now][0]]){ now=ch[now][0]; continue; } if(x>size[ch[now][0]]+tot[now]){ x-=size[ch[now][0]]+tot[now]; now=ch[now][1]; continue; } else return data[now]; } } void front(int x){ int now=root; while(1){ if(!now)return ; if(data[now]<x) ans=now,now=ch[now][1]; else now=ch[now][0]; } return ; } void back(int x){ int now=root; while(1){ if(!now)return ; if(x<data[now]) ans=now,now=ch[now][0]; else now=ch[now][1]; } return ; } int main(){ freopen("in","r",stdin); // srand(time(0)); read(n); int opt,x; while(n--){ read(opt);read(x); switch(opt){ case 1:ins(root,x);break; case 2:del(root,x);break; case 3:printf("%d\n",get_rank(x));break; case 4:printf("%d\n",get_num(x));break; case 5:ans=0;front(x);printf("%d\n",data[ans]);break; case 6:ans=0;back(x);printf("%d\n",data[ans]);break; default :puts("ERROR IN INPUT");return 0; } } return 0; }
SBTSBT 版:
#include<bits/stdc++.h> using namespace std; #define cl(x) memset(x,0,sizeof(x)) #define rg register template <typename _Tp> inline void read(_Tp&x){ char c11=getchar();x=0;bool booo=0; while(c11!='-'&&!isdigit(c11))c11=getchar();if(c11=='-'){c11=getchar();booo=1;} while(isdigit(c11)){x=x*10+c11-'0';c11=getchar();}if(booo)x=-x;return ; } const int N=1005000; struct sbt{ int rt,sz; int data ,ch [2],size ; void clear(){ rt=sz=0; cl(data),cl(ch),cl(size); } void zig(int &p){ int k=ch[p][1]; ch[p][1]=ch[k][0]; ch[k][0]=p; size[k]=size[p]; size[p]=size[ch[p][0]]+size[ch[p][1]]+1; p=k; } void zag(int &p){ int k=ch[p][0]; ch[p][0]=ch[k][1]; ch[k][1]=p; size[k]=size[p]; size[p]=size[ch[p][0]]+size[ch[p][1]]+1; p=k; } void maintain(int &p,bool flag){ #define L ch[p][0] #define R ch[p][1] #define LL ch[ch[p][0]][0] #define LR ch[ch[p][0]][1] #define RL ch[ch[p][1]][0] #define RR ch[ch[p][1]][1] if(!flag) if(size[LL]>size[R])zag(p); else if(size[LR]>size[R]){zig(L);zag(p);} else return ; else if(size[RR]>size[L])zig(p); else if(size[RL]>size[L]){zag(R);zig(p);} else return ; maintain(L,0); maintain(R,1); maintain(p,1); maintain(p,0); return ; } void ins(int &p,int x){ if(!p){ p=++sz;data[sz]=x,size[sz]=1; return ; } ++size[p]; ins(ch[p][data[p]<=x],x); maintain(p,x>=data[p]); } int erase(int &p,int x){ --size[p];int tmp; if(x==data[p]||(x<data[p]&&!ch[p][0])||(data[p]<x&&!ch[p][1])){ tmp=data[p]; if(!ch[p][0]||!ch[p][1])p=ch[p][0]+ch[p][1]; else data[p]=erase(ch[p][0],data[p]+1); return tmp; } tmp=erase(ch[p][data[p]<=x],x); return tmp; } int rank(int &p,int x){ if(!p)return 1;int tmp=0; if(x<=data[p])tmp=rank(ch[p][0],x); else tmp=size[ch[p][0]]+1+rank(ch[p][1],x); return tmp; } int num(int &p,int x){ if(x==size[ch[p][0]]+1)return data[p]; if(x<=size[ch[p][0]])return num(ch[p][0],x); return num(ch[p][1],x-1-size[ch[p][0]]); } int front(int &p,int x){ if(!p)return x;int tmp; if(x<=data[p])tmp=front(ch[p][0],x); else{tmp=front(ch[p][1],x);if(tmp==x)tmp=data[p];} return tmp; } int back(int &p,int x){ if(!p)return x;int tmp; if(data[p]<=x)tmp=back(ch[p][1],x); else{tmp=back(ch[p][0],x);if(tmp==x)tmp=data[p];} return tmp; } }T; int main(){ freopen("in","r",stdin); int m;read(m); T.clear(); int &rt=T.rt=0; while(m--){ int opt,x; read(opt);read(x); switch(opt){ case 1:T.ins(rt,x);break; case 2:T.erase(rt,x);break; case 3:printf("%d\n",T.rank(rt,x));break; case 4:printf("%d\n",T.num(rt,x));break; case 5:printf("%d\n",T.front(rt,x));break; case 6:printf("%d\n",T.back(rt,x));break; } } return 0; }
相关文章推荐
- [BZOJ 3224]普通平衡树(忽然想要存个模板 Treap/Splay)
- 洛谷 P3369 BZOJ 3224 【模板】普通平衡树(Treap/SBT)
- BZOJ 3224 洛谷 3369 【模板】普通平衡树(Treap/SBT)
- BZOJ3224:普通平衡树(含SBT、Treap、Splay模板)
- 【模板】【bzoj3224】Tyvj 1728 普通平衡树 Splay
- 【bzoj3224】Tyvj 1728 普通平衡树 01Trie姿势+平衡树的四种姿势 :splay,旋转Treap,非旋转Treap,替罪羊树
- 【Treap】[BZOJ 3224]Tyvj 1728 普通平衡树 & 非旋转实现
- 【bzoj 3224】普通平衡树(Treap 模板)
- 【模板】普通平衡树(Treap/SBT) 洛谷 3369 splay
- Treap模板 BZOJ 3224: Tyvj 1728 普通平衡树
- bzoj3224 普通平衡树(splay 模板)
- BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]
- BZOJ 3224 普通平衡树 平衡树 ( Treap , SBT , Splay ,替罪羊树 ,非旋转 Treap )
- Splay练习1——P3369 【模板】普通平衡树(Treap/SBT)
- bzoj 3224: Tyvj 1728 普通平衡树 (Splay模板)
- [学习笔记] bzoj3224 普通平衡树:splay模板
- 3224: Tyvj 1728 普通平衡树 P3369 【模板】普通平衡树(Treap/SBT)Treap
- [bzoj3224]Tyvj 1728 普通平衡树——splay模板
- bzoj 3224: Tyvj 1728 普通平衡树(splay 模板题)
- 【模板】【bzoj3224】Tyvj 1728 普通平衡树 Treap