del运行效率特别差,已知这个测试点要做5e5次插入然后做5e5次删除,插入的数两两不同且按升序插入和删除。
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct splay_tree
{
struct node
{
node *ch[2],*fa;
int val,cnt,siz;
node(node* _fa=0,int _val=0)
{
ch[0]=ch[1]=0;
fa=_fa;
val=_val;
cnt=siz=1;
}
bool wson()
{
return fa&&fa->ch[1]==this;
}
void update()
{
siz=cnt+(ch[0]?ch[0]->siz:0)+(ch[1]?ch[1]->siz:0);
return;
}
}*root;
int size(node* x)
{
return x?x->siz:0;
}
void link(node *x,node *f,bool opt)
{
if(x)
{
x->fa=f;
}
if(f)
{
f->ch[opt]=x;
}
else
{
root=x;
}
return;
}
void rotate(node* x)
{
node *y=x->fa,*z=y->fa;
bool k=x->wson();
link(x,z,y->wson());
link(x->ch[!k],y,k);
link(y,x,!k);
y->update();
x->update();
return;
}
void splay(node* x,node* k)
{
while(x->fa!=k)
{
node *y=x->fa,*z=y->fa;
if(z!=k)
{
x->wson()^y->wson()?rotate(y):rotate(x);
}
rotate(x);
}
if(!k)
{
root=x;
}
return;
}
void find(int val)
{
node *x=root;
while(x->ch[val>x->val]&&x->val!=val)
{
x=x->ch[val>x->val];
}
splay(x,0);
return;
}
node* get_pre(int val)
{
find(val);
node* x=root;
if(x->val<val)
{
return x;
}
x=x->ch[0];
while(x->ch[1])
{
x=x->ch[1];
}
splay(x,0);
return x;
}
node* get_nxt(int val)
{
find(val);
node* x=root;
if(x->val>val)
{
return x;
}
x=x->ch[1];
while(x->ch[0])
{
x=x->ch[0];
}
splay(x,0);
return x;
}
void del(int val)
{
node* pre=get_pre(val);
node* nxt=get_nxt(val);
splay(pre,0);
splay(nxt,pre);
node* del=nxt->ch[0];
if(del->cnt>1)
{
del->cnt--;
splay(del,0);
}
else
{
delete del;
nxt->ch[0]=0;
splay(nxt,0);
}
return;
}
int get_rank(int val)
{
insert(val);
int res=root->ch[0]->siz;
del(val);
return res;
}
int get_val(int rank)
{
node* x=root;
while(1)
{
node* y=x->ch[0];
if(size(y)+x->cnt<rank)
{
rank-=size(y)+x->cnt;
x=x->ch[1];
}
else
{
if(size(y)>=rank)
{
x=x->ch[0];
}
else
{
break;
}
}
}
splay(x,0);
return x->val;
}
void insert(int val)
{
node *x=root,*p=0;
while(x&&x->val!=val)
{
p=x;
x=x->ch[val>x->val];
}
if(x)
{
x->cnt++;
}
else
{
x=new node(p,val);
if(p)
{
p->ch[val>p->val]=x;
}
else
{
root=x;
}
}
splay(x,0);
return;
}
splay_tree()
{
insert(-2e9);
insert(2e9);
}
}g;
int n,q,lastans,ans;
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
freopen("P6136_11.in","r",stdin);
cin>>n>>q;
while(n--)
{
int x;
cin>>x;
g.insert(x);
}
while(q--)
{
int opt,x;
cin>>opt>>x;
x^=lastans;
switch(opt)
{
case 1:g.insert(x);break;
case 2:g.del(x);break;
case 3:ans^=lastans=g.get_rank(x);break;
case 4:ans^=lastans=g.get_val(x+1);break;
case 5:ans^=lastans=g.get_pre(x)->val;break;
case 6:ans^=lastans=g.get_nxt(x)->val;break;
}
}
cout<<ans<<flush;
return 0;
}