您的位置:首页 > 其它

【模板】bzoj-3224普通平衡树(splay&treap&SBT)

2018-01-03 22:29 603 查看
先吐槽一下,要找块好模板真不容易,毕竟大家都有各自的代码风格,强迫自己去看非自己风格的代码真是痛苦,所以在网上添加一种类型的模板

最近才发现这题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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: