rt,参考 lyd老师 的紫书代码,有部分区别,但由于水平原因未能发现错误,自造数据没问题。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define db double
#define inl inline
#define re register
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define F(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define DF(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define G(i,u) for(int (i)=head[u];(i);(i)=nxt[(i)])
inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}return x*f;}
//以上为头文件
const int SIZE=100005;
struct BST{
int ls,rs,cnt,size;
ll dat;
ll val;
}t[SIZE];
int len,root;
void Update(int p){
t[p].size=t[t[p].ls].size+t[t[p].rs].size+t[p].cnt;
return ;
}
int NewN(ll val){
t[++len].val=val;
t[len].size=1;
t[len].cnt=1;
t[len].dat=rand();
return len;
}
void BuildT(){
NewN(-LINF);NewN(LINF);
root=1;
t[1].rs=2;t[0].ls=1;
Update(1);
return ;
}
int GetV(ll val,int p=root){
if(p==0) return 0;
if(t[p].val==val) return p;
return t[p].val>val ? GetV(val,t[p].ls) : GetV(val,t[p].rs);
}
void zig(int &p){
int q=t[p].ls;
t[p].ls=t[q].rs; t[q].rs=p; p=q;
Update(t[p].rs);
Update(p);
return ;
}
void zag(int &p){
int q=t[p].rs;
t[p].rs=t[q].ls; t[q].ls=p; p=q;
Update(t[p].ls);
Update(p);
return ;
}
void InsertV(ll val,int &p){
if(p==0){
p=NewN(val);
return;
}
if(val==t[p].val){
t[p].cnt++;Update(p);
return;
}
if(val<t[p].val){
InsertV(val,t[p].ls);
if(t[p].dat<t[t[p].ls].dat) zig(p);
}
else{
InsertV(val,t[p].rs);
if(t[p].dat<t[t[p].rs].dat) zag(p);
}
Update(p);
return ;
}
ll NextN(ll val){
int ans=2,p=root;
while(p){
if(t[p].val==val){
if(t[p].rs>0){
p=t[p].rs;
while(t[p].ls>0) p=t[p].ls;
ans=p;
}
break;
}
if(t[p].val>val && t[p].val<t[ans].val) ans=p;
p= t[p].val>val ? t[p].ls : t[p].rs;
}
return t[ans].val;
}
ll PreN(ll val){
int ans=1,p=root;
while(p){
if(t[p].val==val){
if(t[p].ls>0){
p=t[p].ls;
while(t[p].rs>0) p=t[p].rs;
ans=p;
}
break;
}
if(t[p].val<val && t[p].val>t[ans].val) ans=p;
p= t[p].val>val ? t[p].ls : t[p].rs;
}
return t[ans].val;
}
void DeleteV(ll val,int &p){
if(p==0) return;
if(val==t[p].val){
if(t[p].cnt>1){
t[p].cnt--; Update(p); return;
}
else{
if(t[p].ls || t[p].rs){
if(t[p].rs==0 || t[t[p].ls].dat>t[t[p].rs].dat){
zig(p);
DeleteV(val,t[p].rs);
}
else{
zag(p);
DeleteV(val,t[p].ls);
}
Update(p);
}
else p=0;
return;
}
}
val<t[p].val ? DeleteV(val,t[p].ls) : DeleteV(val,t[p].rs);
return;
}
int VtoR(ll val,int p){
if(p==0) return 1;
//cout<<p<<endl;
if(val==t[p].val) return t[t[p].ls].size+1;
if(val<t[p].val) return VtoR(val,t[p].ls);
return VtoR(val,t[p].rs)+t[t[p].ls].size+t[p].cnt;
}
ll RtoV(ll rank,int p){
rank++;
if(p==0) return LINF;
if(t[t[p].ls].size>=rank) return RtoV(rank-1,t[p].ls);
if(t[t[p].ls].size+t[p].cnt>=rank) return t[p].val;
return RtoV(rank-1-t[t[p].ls].size-t[p].cnt,t[p].rs);
}
ll n,opt,x;
int main(){
BuildT();
n=read();
F(i,1,n){
opt=read(),x=read();
switch(opt){
case 1: InsertV(x,root); break;
case 2: DeleteV(x,root); break;
case 3: cout<<VtoR(x,root)-1<<endl; break;
case 4: cout<<RtoV(x,root)<<endl; break;
case 5: cout<<PreN(x)<<endl; break;
case 6: cout<<NextN(x)<<endl; break;
}
/*F(j,1,len){
printf("%d %d %d %lld %lld %d %d\n",j,t[j].ls,t[j].rs,t[j].val,t[j].dat,t[j].cnt,t[j].size);
}//调试代码*/
}
return 0;
}