Splay求调48pts
查看原帖
Splay求调48pts
820807
SafariMo楼主2023/10/12 11:29
#include <bits/stdc++.h>
#define f(c,a,b) for(c=a;c<=b;++c)
#define fd(c,a,b)for(c=b;c>=a;--c)
#define ll unsigned long long
#define mp make_pair
#define il inline
#define ri register
#define co const
using namespace std;
const int N=1e6+2e5;
struct Node {
	int val,size,cnt,son[2],fa;
} tree[N];
int n,m,k;
int root,tot;
il void update(co int x) {
	tree[x].size=tree[x].cnt+tree[tree[x].son[1]].size+tree[tree[x].son[0]].size;
}
il void rotate(co int x) {
	co int fa=tree[x].fa,gfa=tree[fa].fa;
	co bool k=(tree[fa].son[1]==x);
	tree[gfa].son[tree[gfa].son[1]==fa]=x;
	tree[x].fa=gfa;
	tree[fa].son[k]=tree[x].son[k^1];
	tree[tree[x].son[k^1]].fa=fa;
	tree[x].son[k^1]=fa;
	tree[fa].fa=x;
	update(fa);
	update(x);
}
il void splay(co int x,co int goal) {
	while(tree[x].fa!=goal) {
		co int fa=tree[x].fa,gfa=tree[fa].fa;
		if(gfa!=goal)
			((tree[gfa].son[0]==fa)^(tree[fa].son[0]==x))?rotate(x):rotate(fa);
		rotate(x);
	}
	if(!goal) root=x;
}
il void find(co int x) {
	if(!root) return;
	ri int u=root;
	while(tree[u].son[x>tree[u].val]&&x!=tree[u].val) u=tree[u].son[x>tree[u].val];
	splay(u,0);
}
il int prenode(ri int x) {
	find(x);
	ri int u=tree[root].son[0];
	while(tree[u].son[1]) u=tree[u].son[1];
	splay(u,0);
	return u;
}
il int nxtnode(ri int x) {
	find(x);
	ri int u=tree[root].son[1];
	while(tree[u].son[0]) u=tree[u].son[0];splay(u,0);
	return u;
}
il void insert(co int x) {
	ri int u=root,fa=0;
	while(u&&tree[u].val!=x) {
		fa=u;
		u=tree[u].son[x>tree[u].val];
	}
	if(u) {
		++tree[u].cnt;
	} else {
		u=++tot;
		if(fa) tree[fa].son[x>tree[fa].val]=u;
		tree[u].fa=fa;
		tree[u].son[0]=tree[u].son[1]=0;
		tree[u].val=x;
		tree[u].cnt=tree[u].size=1;
	}
	splay(u,0);
}
il int findkth(ri int x){
	ri int u=root;
	while(1){
		if(!u) return 0-3;
		if(x<=tree[tree[u].son[0]].size) u=tree[u].son[0];
		else {
			x-=(tree[tree[u].son[0]].size+tree[u].cnt);
			if(x<=0) {
				splay(u,0);
				return u; 
			}
			else u=tree[u].son[1];
		}
	} 
}
il void del(co int x){
	co int pre=prenode(x);
	co int suf=nxtnode(x);
	splay(pre,0);
	splay(suf,pre);
	co int u=tree[suf].son[0];
	if(tree[u].cnt>1) {
		--tree[u].cnt;
		splay(u,0);
	}
	else{
		tree[suf].son[0]=tree[tree[suf].son[0]].size=0;
		//splay(pre,0);
	}
}
il int getscore(co int x){
	find(x);
	return tree[tree[root].son[0]].size;
}
il int read() {
	ri int ans=0;
	ri char c=getchar();
	ri bool neg=0;
	while((c<'0')|(c>'9')) neg^=!(c^'-'),c=getchar();
	while((c>='0')&(c<='9')) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
	return neg?-ans:ans;
}
il int solve(co int op,co int x){
	ri int ans=-3;
	if(op==1) insert(x);
	else if(op==2) del(x);
	else if(op==3) ans=getscore(x)+1;
	else if(op==4) {
		int res=findkth(x+1);
		if(tree[res].val==(1<<30)+3||res<0) res=prenode((1<<30)+3);
		ans=tree[res].val;
	}
	else if(op==5){
		insert(x);
		ans=tree[prenode(x)].val;
		del(x);
	}
	else{
		insert(x);
		ans=tree[nxtnode(x)].val;
		del(x);
	}
    return ans;
}

signed main() {
	insert(-1);
	insert((1<<30)+3);
	int TT=read(),T=read();
	while(TT--){
		insert(read());
	}
	int Ans=0;
	ri int Lst=0;
	do{
		co int op=read(),x=read()^Lst;
		co int res=solve(op,x);
		if(op>2){
			Ans^=res;
		//	cout<<res<<endl;
			Lst=res;
		}
	}
	while(--T);
	cout<<Ans;
	return 0;
}
2023/10/12 11:29
加载中...