这道题,大概做了n遍了。。。。。
这次是spaly,这道题采取的是递归的写法
在getrank,getnum处与之前的有些许不同,需要注意
据说splay还可以简化,有时间研究一下
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define inf 0x7fffffff
//#define ll long long
#define int long long
//#define double long double
#define re int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
using namespace std;
const int mod=998244353;
const int M=2e6+5;
const int N=3e5+5;//?????????? 4e8
struct node
{
int l,r,val,sz,cnt;
}e[N];
int tot,rt[N];
int root;
void newnode(int &p,int &val)
{
p=++tot;
e[p].val=val;
e[p].sz++;
e[p].cnt++;
}
void update(int p)
{
e[p].sz=e[e[p].l].sz+e[e[p].r].sz+e[p].cnt;
}
void zig(int &p)
{
int l=e[p].l;
e[p].l=e[l].r;
e[l].r=p;
p=l;
update(e[p].r);update(p);
}
void zag(int &p)
{
int r=e[p].r;
e[p].r=e[r].l;
e[r].l=p;
p=r;
update(e[p].l);update(p);
}
void splaying(int x,int &y)
{
if(x==y) return;
int &l=e[y].l,&r=e[y].r;
if(x==l) zig(y);
else if(x==r) zag(y);
else//双旋
{
if(e[x].val<e[y].val)
{
if(e[x].val<e[l].val) splaying(x,e[l].l),zig(y),zig(y);
else splaying(x,e[l].r),zag(l),zig(y);
}
else
{
if(e[x].val>e[r].val) splaying(x,e[r].r),zag(y),zag(y);
else splaying(x,e[r].l),zig(r),zag(y);
}
}
}
void insert(int &p,int &val)
{
if(!p) newnode(p,val),splaying(p,root);
else
{
if(val<e[p].val) insert(e[p].l,val);
else if(val>e[p].val) insert(e[p].r,val);
else e[p].sz++,e[p].cnt++,splaying(p,root);
}
}
void delnode(int p)
{
splaying(p,root);
if(e[p].cnt>1) e[p].sz--,e[p].cnt--;
else if(e[root].r)
{
int p=e[root].r;
while(e[p].l) p=e[p].l;
splaying(p,e[root].r);
e[e[root].r].l=e[root].l;
root=e[root].r;
update(root);
}
else root=e[root].l;
}
void remove(int p,int &val)
{
if(e[p].val==val) delnode(p);
else if(val<e[p].val) remove(e[p].l,val);
else remove(e[p].r,val);
}
int getrank(int val)
{
int p=root,rank=1;
while(p)
{
if(e[p].val==val)//找到
{
rank+=e[e[p].l].sz;
splaying(p,root);
break;
}
if(val<=e[p].val) p=e[p].l;
else
{
rank+=e[e[p].l].sz+e[p].cnt;
p=e[p].r;
}
}
return rank;
}
int getnum(int rank)
{
int p=root;
while(p)
{
int lsz=e[e[p].l].sz;
if(lsz+1<=rank&&rank<=lsz+e[p].cnt)//注意这里
{
splaying(p,root);
break;
}
else if(lsz>=rank) p=e[p].l;
else
{
rank-=lsz+e[p].cnt;
p=e[p].r;
}
}
return e[p].val;
}
int last(int x)
{
return getnum(getrank(x)-1);
}
int next(int x)
{
return getnum(getrank(x+1));
}
void solve()
{
int m;
cin>>m;
while(m--)
{
int op,x;
scanf("%lld%lld",&op,&x);
if(op==1) insert(root,x);
if(op==2) remove(root,x);
if(op==3) printf("%lld\n",getrank(x));
if(op==4) printf("%lld\n",getnum(x));
if(op==5) printf("%lld\n",last(x));
if(op==6) printf("%lld\n",next(x));
}
}
signed main()
{
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
// printf("Case #%d: ",index);
solve();
// puts("");
}
return 0;
}
/*
*/