splay求调,TLE#11
查看原帖
splay求调,TLE#11
957501
syp11楼主2024/10/17 13:55

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;
}
2024/10/17 13:55
加载中...