【伸展树】[CQBZOJ2803]普通平衡树splay top_down模板
贴模板
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 500000
using namespace std;
int n;
void Read(int &x){
char c;
bool f=0;
while(c=getchar(),c!=EOF){
if(c=='-')
f=1;
if(c>='0'&&c<='9'){
x=c-'0';
while(c=getchar(),c>='0'&&c<='9')
x=x*10+c-'0';
ungetc(c,stdin);
if(f)
x=-x;
return;
}
}
}
struct node{
int cnt,val,size;
node *ch[2];
}splay_tree[MAXN+10],*tcnt=splay_tree,*nil=splay_tree,*root=nil;
inline void update(node *p){
p->size=p->ch[0]->size+p->ch[1]->size+p->cnt;
}
void single_Rotate(int d){
/* node *y=root->ch[!d];
nlr[d]->ch[!d]=root;
root->ch[!d]=nil;
nlr[d]=root;
root=y;*/
node *x=root->ch[!d];
root->ch[!d]=nil->ch[!d];
nil->ch[!d]=root;
root=x;
}
void double_Rotate(int d){
/*node *x=root->ch[!d];
node *y=x->ch[!d];
root->ch[!d]=x->ch[d];
x->ch[d]=root;
x->ch[!d]=nil;
nlr[d]->ch[!d]=x;
nlr[d]=x;
root=y;*/
node *x=root->ch[!d];
node *y=x->ch[!d];
root->ch[!d]=x->ch[d];
x->ch[d]=root;
x->ch[!d]=nil->ch[!d];
nil->ch[!d]=x;
update(root);
root=y;
}
inline void init(node *p){
p->ch[0]=p->ch[1]=nil;
p->cnt=0;
}
inline void finish(){
/*nlr[0]->ch[1]=root->ch[0];
nlr[1]->ch[0]=root->ch[1];
root->ch[0]=nil->ch[1];
root->ch[1]=nil->ch[0];
*/
for(int d=0;d<2;d++){
node *x=root->ch[d],*y;
while(nil->ch[!d]!=nil){
y=nil->ch[!d]->ch[!d];
nil->ch[!d]->ch[!d]=x;
x=nil->ch[!d];
update(x);
nil->ch[!d]=y;
}
root->ch[d]=x;
}
update(root);
}
void search(int val){
bool d,dd;
while(root!=nil){
if(root->val==val)
break;
d=val>root->val;
if(root->ch[d]==nil)
single_Rotate(!d);
else if(root->ch[d]->val==val)
single_Rotate(!d);
else{
dd=val>root->ch[d]->val;
if(d==dd)
double_Rotate(!d);
else
single_Rotate(!d),single_Rotate(!dd);
}
}
}
void insert(int val){
search(val);
if(root==nil){
root=++tcnt;
init(root);
root->val=val;
}
root->cnt++;
finish();
}
int find_pos(int val){
search(val);
finish();
return root->ch[0]->size+1;
}
void search_pos(int pos){
bool d,dd;
node *p;
while(root!=nil){
if(pos<=root->ch[0]->size)
d=0;
else if(pos>root->ch[0]->size+root->cnt)
d=1,pos-=root->ch[0]->size+root->cnt;
else
return;
p=root->ch[d];
if(pos<=p->ch[0]->size)
dd=0;
else if(pos>p->ch[0]->size+p->size)
dd=1;
else{
single_Rotate(!d);
continue;
}
if(d==dd)
double_Rotate(!d);
else{
single_Rotate(!d),single_Rotate(!dd);
}
}
}
int pos_find(int pos){
search_pos(pos);
finish();
return root->val;
}
void del(int val){
search(val);
finish();
if(root->cnt>1){
root->cnt--;
return;
}
if(root->ch[0]==nil)
root=root->ch[1];
else if(root->ch[1]==nil)
root=root->ch[0];
else{
node *p=root;
root=root->ch[0];
search_pos(root->size);
finish();
root->ch[1]=p->ch[1];
}
}
int find_fr(int val){
insert(val);
search_pos(root->ch[0]->size);
finish();
int ret=root->val;
del(val);
return ret;
}
int find_bk(int val){
insert(val);
search_pos(root->ch[0]->size+root->cnt+1);
finish();
int ret=root->val;
del(val);
return ret;
}
int main()
{
init(nil);
Read(n);
int a,b;
while(n--){
Read(a),Read(b);
if(a==1)
insert(b);
else if(a==2)
del(b);
else if(a==3)
printf("%d\n",find_pos(b));
else if(a==4)
printf("%d\n",pos_find(b));
else if(a==5)
printf("%d\n",find_fr(b));
else
printf("%d\n",find_bk(b));
}
}