【树】【平衡树】Splay自顶向下模板
操作1插入x
操作2删除x
操作3查询x排名
操作4查询排名为x的数
操作5查询x的前驱
操作6查询x的后继
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct node{
int sz, val;
node *ch[2];
node(){ch[0] = ch[1] = this; val = sz = 0;}
node *resize(){return sz=ch[0]->sz+ch[1]->sz+1, this;}
}Tnull, *nil=&Tnull, *root;
node *newnode(node *lch, node *rch, int v){
node *ret = new node;
ret->val = v;
ret->ch[0] = lch, ret->ch[1] = rch;
return ret;
}
void build(){root = (newnode(nil, nil, 100000000))->resize();}
void Zig(bool d){
node *tmp = root->ch[d];
root->ch[d] = nil->ch[d];
nil->ch[d] = root;
root = tmp;
}
void ZigZig(bool d){
node *tmp = root->ch[d]->ch[d];
root->ch[d]->ch[d] = nil->ch[d];
nil->ch[d] = root->ch[d];
root->ch[d] = nil->ch[d]->ch[!d];
nil->ch[d]->ch[!d] = root->resize();
root = tmp;
}
void Finish(bool d){
node *p=root->ch[!d], *t=nil->ch[d];
while(t != nil){
t = nil->ch[d]->ch[d];
nil->ch[d]->ch[d] = p;
p = nil->ch[d]->resize();
nil->ch[d] = t;
}
root->ch[!d] = p;
}
void Select(int u){
bool d, dd; int t;
while(true){
d = (t = root->ch[0]->sz) < u;
if(t == u || root->ch[d] == nil) break;
if(d) u -= t + 1;
dd = (t = root->ch[d]->ch[0]->sz) < u;
if(t == u || root->ch[d]->ch[dd] == nil){Zig(d);break;}
if(dd) u -= t + 1;
if(d == dd) ZigZig(dd);
else Zig(d), Zig(dd);
}
Finish(0); Finish(1);
root->resize();
}
void Search(int u){
bool d, dd;
while(true){
d = root->val < u;
if(root->ch[d] == nil) break;
dd = root->ch[d]->val < u;
if(root->ch[d]->ch[dd] == nil){Zig(d); break;}
if(d == dd) ZigZig(dd);
else Zig(d), Zig(dd);
}
Finish(0); Finish(1);
root->resize();
if(root->val < u) Select(root->ch[0]->sz+1);
}
void Insert(int v){
Search(v);
node *newroot = newnode(root->ch[0], root, v);
root->ch[0] = nil;
root->resize();
root = newroot->resize();
}
void Delete(int v){
Search(v);
if(root->val != v) return ;
node *oldroot = root;
root = oldroot->ch[1];
Select(0);
root->ch[0] = oldroot->ch[0];
root->resize();
delete oldroot;
}
int XRank(int x){
Select(x-1);
return root->val;
}
int FRank(int x){
Search(x);
return root->ch[0]->sz+1;
}
int Pre(int x){
Search(x);
Select(root->ch[0]->sz-1);
return root->val;
}
int Bak(int x){
Search(x);
if(root->val != x)
return root->val;
Search(x+1);
return root->val;
}
int main(){
build();
int n, ord, x;
scanf("%d", &n);
for(int i=1;i<=n;i++){
scanf("%d%d", &ord, &x);
switch(ord){
case 1: Insert(x);
break;
case 2: Delete(x);
break;
case 3: printf("%d\n", FRank(x));
break;
case 4: printf("%d\n", XRank(x));
break;
case 5: printf("%d\n", Pre(x));
break;
case 6: printf("%d\n", Bak(x));
break;
}
}
return 0;
}