RT。发题目讨论区估计没人理,所以发这了。
用的是指针Splay,马蜂还是好认
使用一个null空节点,和两个哨兵-INF,INF
谢谢各位大佬
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int INF=INT_MAX;
#define AS_RSON 0
#define AS_LSON 1
namespace SplayContainer{
class _;
_ *null;
class _{
public:
_ *ls,*rs,*fa;
int siz,val,cnt;
_(){
ls=rs=fa=null;
siz=val=cnt=0;
}
_(int v){
ls=rs=fa=null;
cnt=siz=1,val=v;
}
void Update(){
this->siz=this->cnt;
this->siz+=ls->siz,this->siz+=rs->siz;
}
void Bind(_ *son,bool as_lson=0){
// printf("[Bind] Binding %d with %cson %d\n",this->val,as_lson?'l':'r',son->val);
if(son==null){
if(as_lson) this->ls=null;
else this->rs=null;
this->Update();
return;
}
son->fa=this;
if(as_lson) this->ls=son;
else this->rs=son;
this->Update();
}
bool Which(_ *obj){//Is lson
return obj==ls;
}
_* Son(bool as_lson=0){
return as_lson?this->ls:this->rs;
}
}*root;
void Initalization(){
null=new _;
null->ls=null->rs=null->fa=null;
root=null;
}
}
using namespace SplayContainer;
void Recycle(_ *&p){
if(p==null) return;
Recycle(p->ls);
Recycle(p->rs);
delete p;
p=null;
}
void Rotate(_ *p){
_ *self=p,*father=p->fa,*grandfa=father->fa;
bool loc1=father->Which(self);
// printf("[Rotate] Rotating self%d,fa%d,grand%d\n",self->val,father->val,grandfa->val);
if(father==root) root=self;
father->Bind(self->Son(!loc1),loc1);
self->Bind(father,!loc1);
self->fa=null;
if(grandfa!=null) grandfa->Bind(self,grandfa->Which(father));
}
void Splay(_ *x,_ *target=null){
while(x->fa!=target){
_ *fa=x->fa,*gfa=fa->fa;
// printf("splay %d(which father is %d) into %d\n",x->val,x->fa->val,target->val);
if(gfa!=target){
if(gfa->Which(fa)==fa->Which(x)) Rotate(fa);
else Rotate(x);
}
Rotate(x);
}
if(target==null) root=x;
}
_* Kth(_ * p,int k){
if(p==null) return null;
if(k<=p->ls->siz) return Kth(p->ls,k);
else if(k>p->ls->siz+p->cnt) return Kth(p->rs,k-p->ls->siz-p->cnt);
else return p;
}
int Rank(int k){
int res=0;_ *cur=root;
while(cur!=null){
if(k<cur->val) cur=cur->ls;
else{
res+=cur->ls->siz;
if(k==cur->val){
Splay(cur);
return res+1;
}
res+=cur->cnt;
cur=cur->rs;
}
}
return res+1;
}
_* Split(int l,int r){
_ *pre=Kth(root,l-1),*nxt=Kth(root,r+1);
// printf("[Split] [%d,%d]\n",l,r);
Splay(pre,null),Splay(nxt,pre);
return nxt;
}
void Insert(int x){
int rnk=Rank(x);
if(root->val==x){
root->cnt++;
return;
}
// printf("Knowing rnk is %d\n",rnk-1);
rnk--;
_ *tar=Split(rnk+1,rnk);
tar->Bind(new _(x),AS_LSON);
}
void Delete(int x){
int rnk=Rank(x);
if(root->cnt>1){
root->cnt--;
return;
}
_ *tar=Split(rnk,rnk);
Recycle(tar->ls);
tar->Update();
}
int Next(int x){
Insert(x);
int ans=Kth(root,Rank(x)+1)->val;
Delete(x);
return ans;
}
int Prev(int x){
Insert(x);
int ans=Kth(root,Rank(x)-1)->val;
Delete(x);
return ans;
}
void Init(){
Initalization();
root=new _(-INF);
root->Bind(new _(INF),AS_RSON);
}
int main(){
int n;cin>>n;
Init();
while(n--){
int op,x;cin>>op>>x;
// cout<<root->val<<endl;
switch(op){
case 1:{
Insert(x);
break;
}
case 2:{
Delete(x);
break;
}
case 3:{
Insert(x);
cout<<Rank(x)-1<<endl;
Delete(x);
break;
}
case 4:{
cout<<Kth(root,x+1)->val<<endl;
break;
}
case 5:{
cout<<Prev(x)<<endl;
break;
}
case 6:{
cout<<Next(x)<<endl;
break;
}
}
}
return 0;
}