救救我吧,有wa有tle
查看原帖
救救我吧,有wa有tle
1079845
BHH985211楼主2024/9/28 20:28
#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;
}
2024/9/28 20:28
加载中...