已经很清晰明了
#include <stdio.h>
#include <algorithm>
using namespace std;
struct node
{
int date;
int cnt=1,siz=1;
const int rawt=rand();
node *lf,*rt;
node(int x){
date=x;
lf=rt=NULL;
}
};
struct treap
{
protected:
node *root;
int siz,u;
void pu(node *cur)
{
if(cur==NULL){return;}
int temp=cur->cnt;
temp+=cur->lf==NULL? 0: cur->lf->siz;
temp+=cur->rt==NULL? 0: cur->rt->siz;
cur->siz=temp;
}
void zig(node *&cur)
{
if(cur==NULL){return;}
node *temp=cur->lf;
cur->lf=temp->rt;
temp->rt=cur;
pu(cur),pu(temp);
cur=temp;
}
void zag(node *&cur)
{
if(cur==NULL){return;}
node *temp=cur->rt;
cur->rt=temp->lf;
temp->lf=cur;
pu(cur),pu(temp);
cur=temp;
}
void insert_sx(int x,node *&cur)
{
if(cur==NULL){cur=new node(x);return;}
if(cur->date==x){cur->cnt++,cur->siz++;}
else if(cur->date>x)
{
insert_sx(x,cur->lf);
if(cur->lf->rawt<cur->rawt)
{zig(cur);}
pu(cur);
}
else
{
insert_sx(x,cur->rt);
if(cur->rt->rawt<cur->rawt)
{zag(cur);}
pu(cur);
}
}
void eraser_sx(int x,node *&cur)
{
if(cur==NULL){return;}
if(cur->date==x)
{
if(cur->cnt>1){cur->cnt--,cur->siz--;return;}
node *curt=cur,*L=cur->lf,*R=cur->rt;
int temp=((L!=NULL)<<1)+(R!=NULL);
switch(temp)
{
case 0: delete cur;cur=NULL;break;
case 1: cur=R; delete curt;break;
case 2: cur=L; delete curt;break;
case 3:{
if(L->rawt<R->rawt)
{zig(cur);eraser_sx(x,cur->rt);}
else{zag(cur);eraser_sx(x,cur->lf);}
pu(cur);
}
}
}
else if(cur->date>x){eraser_sx(x,cur->lf);pu(cur);}
else{eraser_sx(x,cur->rt);pu(cur);}
}
int valrank_sx(int x,node *cur)
{
if(cur==NULL){return 0;}
if(x<cur->date){return valrank_sx(x,cur->lf);}
int temp=cur->lf==NULL? 0: cur->lf->siz;
if(x==cur->date){return temp;}
return valrank_sx(x,cur->rt)+temp+cur->cnt;
}
int rankval_sx(int rk,node *cur)
{
if(cur==NULL){return 0;}
int temp=cur->lf==NULL? 0: cur->lf->siz;
if(rk<=temp){return rankval_sx(rk,cur->lf);}
if(rk<=temp+cur->cnt){return cur->date;}
return rankval_sx(rk-temp-cur->cnt,cur->rt);
}
void findlt_sx(int x,node *cur)
{
if(cur==NULL){return;}
if(cur->date<x){u=max(u,cur->date);findlt_sx(x,cur->rt);}
else{findlt_sx(x,cur->lf);}
}
void findnx_sx(int x,node *cur)
{
if(cur==NULL){return;}
if(cur->date>x){u=min(u,cur->date);findnx_sx(x,cur->lf);}
else{findnx_sx(x,cur->rt);}
}
public:
inline void insert(int x){insert_sx(x,root);}
inline void eraser(int x){eraser_sx(x,root);}
inline int valrank(int x){return valrank_sx(x,root)+1;}
inline int rankval(int rk){return rankval_sx(rk,root);}
inline int findlt(int x){u=INT_MIN;if(root==NULL){return u;}findlt_sx(x,root);return u;}
inline int findnx(int x){u=INT_MAX;if(root==NULL){return u;}findnx_sx(x,root);return u;}
}t;
int G,cz,y;
int main()
{
scanf("%d",&G);
while(G--)
{
scanf("%d%d",&cz,&y);
switch(cz)
{
case 1: t.insert(y);break;
case 2: t.eraser(y);break;
case 3: printf("%d\n",t.valrank(y));break;
case 4: printf("%d\n",t.rankval(y));break;
case 5: printf("%d\n",t.findlt(y));break;
case 6: printf("%d\n",t.findnx(y));break;
}
}
return 0;
}