BHH985211 @ 2024-09-28 20:28:50
#include<bits/stdc++.h>
using namespace std;
struct node{
int s[2];//左右儿子
int p;//父亲
int v;//节点数值
int cnt;//出现几次
int size;//子树大小
void init(int p1,int v1){
p=p1,v=v1;
cnt=size=1;
}
}tr[2000005];
int root,idx;//根节点编号,节点个数
void pushup(int x)
{
tr[x].size=tr[tr[x].s[0]].size+tr[tr[x].s[1]].size+tr[x].cnt;
}
void rotate(int x)
{
int y=tr[x].p,z=tr[y].p;//y父亲z爷爷
int k=tr[y].s[1]==x;//K记录x是y的左or右节点
tr[y].s[k]=tr[x].s[k^1];
tr[tr[x].s[k^1]].p=y;
tr[x].s[k^1]=y;
tr[y].p=x;
tr[z].s[tr[z].s[1]==y]=x;
tr[x].p=z;
pushup(y),pushup(x);
}
void splay(int x,int k)//将x移到k下
{
while(tr[x].p!=k){//x的父亲等于k结束
int y=tr[x].p,z=tr[y].p;
if(z!=k) (tr[y].s[0]==x)^(tr[z].s[0]==y)? rotate(x):rotate(y);//直线型转中间节点
rotate(x);
}
if(k==0) root=x;
}
void insert(int v)
{
int x=root,p=0;//x来移动,p是父节点
while(x&&tr[x].v!=v)
p=x,x=tr[x].s[v>tr[x].v];
if(x) tr[x].cnt++;
else{
x=++idx;
tr[p].s[v>tr[p].v]=x;
tr[x].init(p,v);
}
splay(x,0);
}
void find(int v){
int x=root;
while(tr[x].s[v>tr[x].v]&&v!=tr[x].v)
x=tr[x].s[v>tr[x].v];
splay(x,0);
}
int get_pre(int v){//返回v前驱编号
find(v);
int x=root;
if(tr[x].v<v) return x;
x=tr[x].s[0];
while(tr[x].s[1]) x=tr[x].s[1];
splay(x,0);
return x;
}
int get_suc(int v){//后继
find(v);
int x=root;
if(tr[x].v>v) return x;
x=tr[x].s[1];
while(tr[x].s[0]) x=tr[x].s[0];
splay(x,0);
return x;
}
void del(int v){//删除
int pre=get_pre(v);
int suc=get_suc(v);
splay(pre,0),splay(suc,pre);
int del=tr[suc].s[0];
if(tr[del].cnt>1)
tr[del].cnt--,splay(del,0);
else
tr[suc].s[0]=0,splay(suc,0);
}
int get_rank(int v){//查询排名
insert(v);
int res=tr[tr[root].s[0]].size;
del(v);
return res;
}
int get_val(int k){
int x=root;
while(1){
int y=tr[x].s[0];
if(tr[y].size+tr[x].cnt<k){
k-=tr[y].size+tr[x].cnt;
x=tr[x].s[1];
}
else if(tr[y].size>=k) x=y;
else break;
}
splay(x,0);
return tr[x].v;
}
int main()
{
insert(-0x3f),insert(0x3f);
int n,m,op,a,last=0,ans=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&a);
insert(a);
}
while(m){
scanf("%d%d",&op,&a);
a^=last;
if(op==1) insert(a);
else if(op==2) del(a);
else if(op==3)
last=get_rank(a),ans^=last;
else if(op==4)
last=get_val(a+1),ans^=last;
else if(op==5)
last=tr[get_pre(a)].v,ans^=last;
else last=tr[get_suc(a)].v,ans^=last;
m--;
}
printf("%d",ans);
return 0;
}
by caoqcTH68127 @ 2024-09-28 20:34:15
啊,头疼。
代码非常的···
by BHH985211 @ 2024-09-28 20:39:37
@caoqcTH68127 知道啦,把插入的两个哨兵-0x3f,0x3f改成(1<<30)+1,就行了,哨兵不够大
by caoqcTH68127 @ 2024-09-29 18:59:16
@BHH985211 ......(你知道你问我干什么)
by BHH985211 @ 2024-09-29 19:45:42
@caoqcTH68127 发了之后才发现