云岁月书 @ 2020-08-07 19:37:57
# include <cstdio>
# define Gc (SS == TT && (TT = (SS = BB) + fread(BB,1,1 << 15,stdin),TT == SS) ? EOF : *SS++)
char BB[1<<15],*SS=BB,*TT=BB;
inline int Read()
{
register int x = 0,f=1;register char ch = Gc;
while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = Gc;}
while(ch <= '9' && ch >= '0'){x = x*10 + (ch^48);ch = Gc;}
return f < 0 ? -x : x;
}
int n,m;
# undef Gc
class Splay_Tree
{
/*
Name :Splay
Code by: 云岁月书
Data : 2020/8/6-18:32 Start 2020/8/7-16:57
*/
//private:
public:
class node
{
public:
node *father,*Son[2];
int Value,Repetition,Size;
node(){Son[0] = Son[1] = father = NULL;Value = Repetition = Size = 0;}
inline void update(){Size = Repetition + (Son[0] == NULL ? 0 : Son[0]->Size) + (Son[1] == NULL ? 0 : Son[1]->Size);}
inline bool Which_Son()
{
if(father == NULL) return NULL;
else return father->Son[1] == this;
}
inline void Clear_Son()
{
if(Son[0] != NULL) {Son[0]->Clear_Son();delete Son[0];}
if(Son[1] != NULL) {Son[1]->Clear_Son();delete Son[1];}
}//定义 0 左 1 右,且左儿子小于当前节点,右儿子大于当前节点。
};
node* root;
inline node* Create_node(const int val)
{
node *temp = new node();
temp->Size = temp->Repetition = 1;
temp->Value = val;
return temp;
}
inline void link(node* son,node* father,const bool Side)
{
if(father != NULL) father->Son[Side] = son;
if(son != NULL) son->father = father;
}
inline void rotate(node* p)//,
{
if(p == root) return ;
node *father = p->father,*grandfather = p->father->father;
int my_side = p->Which_Son(),fa_side = father->Which_Son();
link(p->Son[my_side^1],father,my_side);//反向子代我位
link(father,p,my_side^1);//父代反向子位
link(p,grandfather,fa_side);//我代父位
father->update();p->update();
}
inline void Splay(node *p,node *Target = NULL)
{
while(p->father != Target)
{
node *father = p->father,*grandfather = p->father->father;
if(grandfather != Target)
{
if(father->Which_Son() == p->Which_Son()) rotate(father);
else rotate(p);
}
rotate(p);
}
if(Target == NULL) root = p;
}
inline void Delete(node* p)
{
if(p->Repetition > 1) {--p->Repetition;p->update();}
else if(p == root){delete p;root = NULL;}
else
{
p->father->Son[p->Which_Son()] = NULL;
p->father->update();
delete p;
}
}
inline int Get_Child_Cnt(const node *p,const int side)
{
/*if(p == NULL) return 0;
else */if(p->Son[side] == NULL) return 0;
else return p->Son[side]->Size;
}
/*Splay 基础操作完成,后面都是 BT 的共有操作*/
//public:
Splay_Tree(){root = NULL;}
~Splay_Tree(){if(root != NULL){root->Clear_Son();delete root;}}
inline node* Root(){return root;}
inline int size(){return root == NULL ? 0 : root->Size;}
inline node* choose_son(const node* p,const int val)
{
if(p->Value > val) return p->Son[0];
else return p->Son[1];
}
inline void find(const int val)
{
if(root == NULL) return ;
node* cur = root;
while(choose_son(cur,val) != NULL && val != cur->Value) cur = choose_son(cur,val);
Splay(cur);
}
inline node* Get_Pre(const int val)
{
find(val);
if(root->Value < val) return root;//因为如果他返回的不是 val 那么他返回的就一定是一个最接近 val 的节点(可以大于可以小于)。
node *cur = root->Son[0];
if(cur == NULL) return root;
while(cur->Son[1] != NULL) cur = cur->Son[1];
return cur;
}
inline node* Get_Suf(const int val)
{
find(val);
if(root->Value > val) return root;
node *cur = root->Son[1];
if(cur == NULL) return root;
while(cur->Son[0] != NULL) cur = cur->Son[0];
return cur;
}
inline void Insert(const int val)
{
if(root == NULL) root = Create_node(val);
else
{
node *cur = root;
while(choose_son(cur,val) != NULL && cur->Value != val) cur = choose_son(cur,val);
if(cur->Value == val)
{
++cur->Repetition;
Splay(cur);
}
else
{
node* ct = Create_node(val);
link(ct,cur,(cur->Value) < val);
Splay(ct);
}
}
}
inline void delete_node(const int val)
{
node *Pre = Get_Pre(val),*Suf = Get_Suf(val);
if(Pre->Value == val && Suf->Value == val) Delete(Pre);
else if(Pre->Value == val){Splay(Suf);Delete(Pre);}
else if(Suf->Value == val){Splay(Pre);Delete(Suf);}
else
{
Splay(Pre);
Splay(Suf,Pre);
Delete(Suf->Son[0]);
}
}
inline int Get_Rank(const int num)//查询num的排名
{
find(num);
node *cur = root;
if(root->Value < num && root->Son[1] != NULL) while(cur->Value > num && cur->Son[0]) cur = cur->Son[0];
int dx = Get_Child_Cnt(root,1),Sz = root->Size,rp = root->Repetition;
return Sz - dx - rp + 1;
}
inline int Get_Num(int k)//查找第 K 大的数
{
node *cur = root;
while(1)
{
if(k <= Get_Child_Cnt(cur,0)) cur = cur->Son[0];//在左子树里
else if(k > Get_Child_Cnt(cur,0) + cur->Repetition) //k比左子树+自己的重复次数还大,说明在右子树里
{
k -= Get_Child_Cnt(cur,0) + cur->Repetition;
cur = cur->Son[1];
}
else return cur->Value;
}
}
void ZXBL(node* p)
{
if(p->Son[0] != NULL) ZXBL(p->Son[0]);
printf("%d ",p->Value);
if(p->Son[1] != NULL) ZXBL(p->Son[1]);
}
} T;
int main()
{
freopen("2.in","r",stdin);
freopen("2.out","w",stdout);
n = Read();m = Read();T.Insert(2147483647);
for(register int i = 1; i <= n; ++i) T.Insert(Read());
/*register*/ int pos,x,last = 0,ans = 0;
while(m--){
pos = Read();x = Read();x ^= last;
if(m == 999994)
{
puts("fuck");
//T.ZXBL(T.root);
//return 0;
}
switch(pos)
{
case 1:
T.Insert(x);
break;
case 2:
T.delete_node(x);
break;
case 3:
last = T.Get_Rank(x);
break;
case 4:
last = T.Get_Num(x);
break;
case 5:
last = T.Get_Pre(x)->Value;
break;
case 6:
last = T.Get_Suf(x)->Value;
break;
}
if(pos > 2)ans ^= last;
}
printf("%d",ans);
return 0;
}
by 云岁月书 @ 2020-08-07 19:48:52
就是 3 号操作有问题,有些时候它查询的会返回的排名多了一。
ps.三号操作有一部分没意义的代码是在Debug乱改的。
by _998344353_ @ 2020-08-07 20:19:40
您能别puts("f**k")吗......