#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
const int N=2e5+5;
struct node{
int s[2],p,v;
int size,cnt;
void init(int _p,int _v){
p=_p, v=_v;
size=cnt=1;
}
}tr[N];
int idx,root;
void pushup(int u){
tr[u].size=tr[tr[u].s[0]].size+tr[tr[u].s[1]].size+tr[u].cnt;
}
void rotate(int x){
int y=tr[x].p, z=tr[y].p;
int k=tr[y].s[1]==x;
tr[z].s[tr[z].s[1]==y]=x, tr[x].p=z;
tr[tr[x].s[k^1]].p=y, tr[y].s[k]=tr[x].s[k^1];
tr[y].p=x, tr[x].s[k^1]=y;
pushup(y), pushup(x);
}
void splay(int x,int k){
while(tr[x].p!=k){
int y=tr[x].p, z=tr[y].p;
if(z!=k)
if((tr[z].s[1]==y) ^ (tr[y].s[1]==x)) rotate(x);
else rotate(y);
rotate(x);
}
if(k==0) root=x;
}
void insert(int v){
int u=root, p=0;
while(u && tr[u].v!=v) p=u, u=tr[u].s[v>tr[u].v];
if(u) tr[u].cnt++, tr[u].size++;
else{
u=++idx;
if(p) tr[p].s[v>tr[p].v]=u;
tr[u].init(p,v); // update the msg of the new node
}
splay(u,0);
}
void find(int v){
int u=root;
if(!u) return;
while(v!=tr[u].v && tr[u].s[v>tr[u].v]) u=tr[u].s[v>tr[u].v];
splay(u,0);
}
int pre(int v){
find(v);
int u=root;
if(tr[u].v<v) return u; // 如果树中所有数的值都没有 v 大,那么 v 的前驱一定是 u
u=tr[u].s[0];
while(tr[u].s[1]) u=tr[u].s[1];
return u;
}
int suf(int v){
find(v);
int u=root;
if(tr[u].v>v) return u; // 如果树中所有数的值都没有 v 小,那么 v 的后继一定是 u
u=tr[u].s[1];
while(tr[u].s[0]) u=tr[u].s[0];
return u;
}
void remove(int v){
int pu=pre(v), su=suf(v);
splay(pu,0);splay(su,pu);
int u=tr[su].s[0]; // the point to remove;
if(tr[u].cnt>1) tr[u].cnt--, splay(u,0);
else tr[su].s[0]=0;
}
int rk_for_num(int k){
int u=root;
while(true){
int ls=tr[u].s[0];
if(tr[ls].size+tr[u].cnt<k) k-=tr[ls].size+tr[u].cnt,u=tr[u].s[1];
else if(tr[ls].size>=k) u=tr[u].s[0];
else return tr[u].v;
}
}
int num_for_rk(int v){
find(v);
return tr[tr[root].s[0]].size+1-1;
}
int main(){
int m; cin>>m;
insert(-INF), insert(INF);
while(m--){
int op, x; op=read(), x=read();
if(op==1) insert(x);
else if(op==2) remove(x);
else if(op==3) cout<<num_for_rk(x)<<endl;
else if(op==4) x++,cout<<rk_for_num(x)<<endl;
else if(op==5) cout<<tr[pre(x)].v<<endl;
else if(op==6) cout<<tr[suf(x)].v<<endl;
}
return 0;
}
Splay 板子
最新推荐文章于 2021-07-08 20:46:40 发布