学了一个星期才学会了三个平衡树……吃枣药丸
SBT到时候再补坑吧……红黑树和AVL就算了
话说那个$o(lglgn)$的VeB树是真的厉害
注:以下都是以BZOJ3224普通平衡树为模板
Splay
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct Splay{
struct node{
int v,fa,son[2],siz,sum;
//0:左儿子 1:右儿子
}t[200001];
int tot,rt;
Splay(){
tot=rt=0;
}
void newnode(int val){
t[++tot].v=val;
t[tot].fa=t[tot].son[0]=t[tot].son[1]=0;
t[tot].sum=t[tot].siz=1;
}
void clear(int x){
t[x].v=t[x].fa=t[x].son[0]=t[x].son[1]=t[x].sum=t[x].siz=0;
}
int lr(int x){
return t[t[x].fa].son[1]==x;
}
void update(int x){
if(x){
t[x].siz=t[x].sum;
if(t[x].son[0])t[x].siz+=t[t[x].son[0]].siz;
if(t[x].son[1])t[x].siz+=t[t[x].son[1]].siz;
}
}
void rotate(int x){
int p=t[x].fa,pp=t[p].fa,ch=lr(x);
t[p].son[ch]=t[x].son[ch^1];
t[t[p].son[ch]].fa=p;
t[p].fa=x;
t[x].son[ch^1]=p;
t[x].fa=pp;
if(pp)t[pp].son[t[pp].son[1]==p]=x;
update(p);
update(x);
}
void splay(int x,int p){
for(int f;(f=t[x].fa)!=p;rotate(x)){
if(t[f].fa!=p)rotate(lr(x)==lr(f)?f:x);
}
if(!p)rt=x;
}
void insert(int x){
if(rt==0){
newnode(x);
rt=tot;
return;
}
int now=rt,f=0;
for(;;){
if(t[now].v==x){
t[now].sum++;
update(now);
update(f);
splay(now,0);
return;
}
f=now;
now=t[now].son[t[now].v<x];
if(!now){
newnode(x);
t[tot].fa=f;
t[f].son[t[f].v<x]=tot;
update(f);
splay(tot,0);
return;
}
}
}
int pre(){
int now=t[rt].son[0];
while(t[now].son[1])now=t[now].son[1];
return now;
}
int nxt(){
int now=t[rt].son[1];
while(t[now].son[0])now=t[now].son[0];
return now;
}
int find(int x){
int ans=0,now=rt;
for(;;){
if(x<t[now].v)now=t[now].son[0];
else{
ans+=(t[now].son[0]?t[t[now].son[0]].siz:0);
if(x==t[now].v){
splay(now,0);
return ans+1;
}
ans+=t[now].sum;
now=t[now].son[1];
}
}
}
int findx(int x){
int now=rt;
for(;;){
if(t[now].son[0]&&x<=t[t[now].son[0]].siz)now=t[now].son[0];
else{
int tmp=(t[now].son[0]?t[t[now].son[0]].siz:0)+t[now].sum;
if(x<=tmp)return t[now].v;
x-=tmp;
now=t[now].son[1];
}
}
}
void del(int x){
int kk=find(x);
if(t[rt].sum>1){
t[rt].sum--;
return;
}
if(!t[rt].son[0]&&!t[rt].son[1]){
clear(rt);
rt=0;
return;
}
if(!t[rt].son[1]){
int rrt=rt;
rt=t[rrt].son[0];
t[rt].fa=0;
clear(rrt);
return;
}
if(!t[rt].son[0]){
int rrt=rt;
rt=t[rrt].son[1];
t[rt].fa=0;
clear(rrt);
return;
}
int pr=pre(),rrt=rt;
splay(pr,0);
t[t[rrt].son[1]].fa=rt;
t[rt].son[1]=t[rrt].son[1];
clear(rrt);
update(rt);
}
int ppre(int x){
insert(x);
int ans=t[pre()].v;
del(x);
return ans;
}
int nnxt(int x){
insert(x);
int ans=t[nxt()].v;
del(x);
return ans;
}
}splaytree;
int n,op,x;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&op,&x);
switch(op){
case 1:splaytree.insert(x);break;
case 2:splaytree.del(x);break;
case 3:printf("%d
",splaytree.find(x));break;
case 4:printf("%d
",splaytree.findx(x));break;
case 5:printf("%d
",splaytree.ppre(x));break;
case 6:printf("%d
",splaytree.nnxt(x));break;
}
}
return 0;
}
Treap(旋转版)
1 #include<iostream>
2 #include<cstdlib>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<ctime>
7 using namespace std;
8 struct Treap{
9 struct node{
10 int v,son[2],siz,k,sum;
11 }t[1000001];
12 int MAX_RAND,tot,rt;
13 Treap(){
14 srand(time(NULL));
15 MAX_RAND=138138138;
16 tot=rt=0;
17 }
18 int rd(){
19 return rand()%MAX_RAND;
20 }
21 void newnode(int val){
22 t[++tot].v=val;
23 t[tot].k=rd();
24 t[tot].son[0]=t[tot].son[1]=0;
25 t[tot].siz=t[tot].sum=1;
26 }
27 void update(int x){
28 t[x].siz=t[t[x].son[0]].siz+t[t[x].son[1]].siz+t[x].sum;
29 }
30 void rotate(int &x,int ch){
31 //ch=0:左;ch=1:右;
32 int s=t[x].son[ch^1];
33 t[x].son[ch^1]=t[s].son[ch];
34 t[s].son[ch]=x;
35 update(x);
36 update(x=s);
37 }
38 void insert(int &x,int v){
39 if(!x){
40 newnode(v);
41 x=tot;
42 return;
43 }
44 if(t[x].v==v){
45 t[x].sum++;
46 t[x].siz++;
47 return;
48 }
49 int ch=t[x].v<v;
50 insert(t[x].son[ch],v);
51 t[x].siz++;
52 if(t[t[x].son[ch]].k<t[x].k)rotate(x,ch^1);
53 }
54 bool del(int &x,int p){
55 if(!x)return false;
56 if(t[x].v==p){
57 if(t[x].sum>1){
58 t[x].siz--;
59 t[x].sum--;
60 return true;
61 }else if(!t[x].son[0]||!t[x].son[1]){
62 x=t[x].son[0]?t[x].son[0]:t[x].son[1];
63 return true;
64 }else{
65 rotate(x,t[t[x].son[0]].k<t[t[x].son[1]].k);
66 del(x,p);
67 }
68 }else{
69 if(!del(t[x].son[t[x].v<p],p))return false;
70 t[x].siz--;
71 return true;
72 }
73 }
74 int find(int x){
75 int u=rt,ans=1;
76 while(u){
77 if(x<t[u].v)u=t[u].son[0];
78 else if(x>t[u].v){
79 ans+=t[t[u].son[0]].siz+t[u].sum;
80 u=t[u].son[1];
81 }else return ans+t[t[u].son[0]].siz;
82 }
83 }
84 int findx(int x){
85 int u=rt;
86 while(u){
87 if(x<=t[t[u].son[0]].siz)u=t[u].son[0];
88 else if(x>t[t[u].son[0]].siz+t[u].sum){
89 x-=t[t[u].son[0]].siz+t[u].sum;
90 u=t[u].son[1];
91 }else return t[u].v;
92 }
93 }
94 int pre(int x){
95 int u=rt,ans;
96 while(u){
97 if(t[u].v<x){
98 ans=t[u].v;
99 u=t[u].son[1];
100 }else u=t[u].son[0];
101 }
102 return ans;
103 }
104 int nxt(int x){
105 int u=rt,ans;
106 while(u){
107 if(t[u].v>x){
108 ans=t[u].v;
109 u=t[u].son[0];
110 }else u=t[u].son[1];
111 }
112 return ans;
113 }
114 }treap;
115 int n,op,x;
116 int main(){
117 scanf("%d",&n);
118 for(int i=1;i<=n;i++){
119 scanf("%d%d",&op,&x);
120 switch(op){
121 case 1:treap.insert(treap.rt,x);break;
122 case 2:treap.del(treap.rt,x);break;
123 case 3:printf("%d
",treap.find(x));break;
124 case 4:printf("%d
",treap.findx(x));break;
125 case 5:printf("%d
",treap.pre(x));break;
126 case 6:printf("%d
",treap.nxt(x));break;
127 }
128 }
129 return 0;
130 }
替罪羊树
1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<cmath>
5 #define inf 233333333
6 using namespace std;
7 const double alpha=0.75;
8 struct ScapegoatTree{
9 struct node{
10 int s,son[2],fa,siz,sum;
11 }t[500001];
12 int rt,tot,cnt,s[200001];
13 ScapegoatTree(){
14 rt=1;
15 cnt=2;
16 t[1].sum=-inf;
17 t[1].siz=2;
18 t[1].son[1]=2;
19 t[2].sum=inf;
20 t[2].siz=1;
21 t[2].fa=1;
22 memset(s,0,sizeof(s));
23 }
24 bool check(int u){
25 return (double)t[u].siz*alpha>=(double)t[t[u].son[0]].siz &&
26 (double)t[u].siz*alpha>=(double)t[t[u].son[1]].siz;
27 }
28 void rec(int u){//把树压扁
29 if(t[u].son[0])rec(t[u].son[0]);
30 s[++tot]=u;
31 if(t[u].son[1])rec(t[u].son[1]);
32 }
33 int build(int l,int r){
34 if(l>r)return 0;
35 int mid=(l+r)/2,k=s[mid];
36 t[k].son[0]=build(l,mid-1);
37 t[k].son[1]=build(mid+1,r);
38 t[t[k].son[0]].fa=k;
39 t[t[k].son[1]].fa=k;
40 t[k].siz=t[t[k].son[0]].siz+t[t[k].son[1]].siz+1;
41 return k;
42 }
43 void rebuild(int u){
44 tot=0;
45 rec(u);
46 int f=t[u].fa,sn=(t[t[u].fa].son[1]==u),now=build(1,tot);
47 t[f].son[sn]=now,t[t[f].son[sn]].fa=f;
48 if(u==rt)rt=now;
49 }
50 void ins(int x){
51 int now=rt;
52 t[++cnt].siz=1;
53 t[cnt].sum=x;
54 for(;;){
55 t[now].siz++;
56 bool sn=(x>=t[now].sum);
57 if(t[now].son[sn])now=(t[now].son[sn]);
58 else{
59 t[now].son[sn]=cnt;
60 t[cnt].fa=now;
61 break;
62 }
63 }
64 int rb=0;
65 for(int i=cnt;i;i=t[i].fa)if(!check(i))rb=i;
66 if(rb)rebuild(rb);
67 }
68 int get(int x){
69 int now=rt;
70 for(;;){
71 if(t[now].sum==x)return now;
72 else now=t[now].son[x>t[now].sum];
73 }
74 }
75 int pre(int u){
76 int now=t[u].son[0];
77 while(t[now].son[1])now=t[now].son[1];
78 return now;
79 }
80 int nxt(int u){
81 int now=t[u].son[1];
82 while(t[u].son[0])now=t[now].son[0];
83 return now;
84 }
85 void del(int x){
86 int u=get(x);
87 if(t[u].son[0]&&t[u].son[1]){
88 int nt=pre(u);
89 t[u].sum=t[nt].sum;
90 u=nt;
91 }
92 int sn=(t[u].son[0])?t[u].son[0]:t[u].son[1],snn=t[t[u].fa].son[1]==u;;
93 t[t[u].fa].son[snn]=sn;
94 t[sn].fa=t[u].fa;
95 for(int i=t[u].fa;i;i=t[i].fa)t[i].siz--;
96 if(u==rt)rt=sn;
97 }
98 int find(int x){
99 int now=rt,ret=0;
100 while(now){
101 if(t[now].sum<x){
102 ret+=t[t[now].son[0]].siz+1;
103 now=t[now].son[1];
104 }else now=t[now].son[0];
105 }
106 return ret;
107 }
108 int findx(int x){
109 int now=rt;
110 for(;;){
111 if(t[t[now].son[0]].siz==x-1)return t[now].sum;
112 else if(t[t[now].son[0]].siz>=x)now=t[now].son[0];
113 else x-=t[t[now].son[0]].siz+1,now=t[now].son[1];
114 }
115 }
116 int ppre(int x){
117 int now=rt,ret=-inf;
118 while(now){
119 if(t[now].sum<x)ret=max(ret,t[now].sum),now=t[now].son[1];
120 else now=t[now].son[0];
121 }
122 return ret;
123 }
124 int nnxt(int x){
125 int now=rt,ret=inf;
126 while(now){
127 if(t[now].sum>x)ret=min(ret,t[now].sum),now=t[now].son[0];
128 else now=t[now].son[1];
129 }
130 return ret;
131 }
132 }scg;
133 int n,op,x;
134 int main(){
135 scanf("%d",&n);
136 for(int i=1;i<=n;i++){
137 scanf("%d%d",&op,&x);
138 switch(op){
139 case 1:scg.ins(x);break;
140 case 2:scg.del(x);break;
141 case 3:printf("%d
",scg.find(x));break;
142 case 4:printf("%d
",scg.findx(x+1));break;
143 case 5:printf("%d
",scg.ppre(x));break;
144 case 6:printf("%d
",scg.nnxt(x));break;
145 }
146 }
147 return 0;
148 }
Size Balanced Tree
待填坑~~~
小测试:
xsy评测Splay133ms,Treap95ms,替罪羊树89ms(Alpha=0.75)
所以说替罪羊树才是最优秀的平衡树!(然而区间操作就萎了)