splay入坑

1829. [Tyvj 1728]普通平衡树

★★★   输入文件: phs.in   输出文件: phs.out
时间限制:1 s   内存限制:128 MB

【题目描述】

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

【输入格式】

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

【输出格式】

对于操作3,4,5,6每行输出一个数,表示对应答案

【样例输入】

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

【样例输出】

106465
84185
492737

【提示】

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]


写完Treap后写splay,感觉真长,代码高亮看得眼前都绿了...新单词get:Predecessor,Successor。
感谢rvalue的板子.
#include<cstdio>
#include<iostream>
#include<cstring>
#define lch ch[0]
#define rch ch[1]
#define kch ch[k]
#define xch ch[k^1]
const int inf=0x7fffffff;
inline int read()
{	char c=getchar();int x=0,y=1;
	while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}
	while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*y;
}
class splay
{
	private:
		struct node
		{	int k,s;
			node* pt;node* ch[2];
			node(const int& key)
			{	this->k=key;this->s=1;
				this->lch=NULL;this->rch=NULL;
			}
			inline int sz(){return this==NULL?0:this->s;}
			inline int key(){return this==NULL?0:this->k;}
			inline void mt(){if(this!=NULL) this->s=this->lch->sz()+this->rch->sz()+1;}
			inline int pos(){return this==this->pt->lch;}
		}*root;
		void rotate(node* root,int k)
		{	node* tmp=root->xch;
			if(root->pt==NULL) this->root=tmp;
			else if(root->pt->lch==root) root->pt->lch=tmp;
			else root->pt->rch=tmp;
			tmp->pt=root->pt;
			root->xch=tmp->kch;
			if(root->xch!=NULL) root->xch->pt=root;
			tmp->kch=root;root->pt=tmp;
			root->mt();tmp->mt();
		}
		void sp(node* root,node* pt=NULL)
		{	while(root->pt!=pt)
			{	int k=root->pos();
				if(root->pt->pt==pt) this->rotate(root->pt,k);
				else
				{	int d=root->pt->pos();
					this->rotate(k==d?root->pt->pt:root->pt,k);
					this->rotate(root->pt,d);
				}
			}
		
		}
	public:
		node* kth(int x)
		{	node* root=this->root;
			while(root!=NULL)
			{	int k=root->lch->sz()+1;
				if(x<k) root=root->lch;
				else if(x==k) return root;
				else x-=k,root=root->rch;
			}
			return NULL;
		}
		int rank(const int& key)
		{	node* root=this->root;
			int rk=1;
			while(root!=NULL)
			{	if(root->key()<key)
					rk+=root->lch->sz()+1,root=root->rch;
				else root=root->lch;
			}
			return rk;
		}
		void insert(const int& key)
		{	int pos=this->rank(key)-1;
			this->sp(this->kth(pos));
			this->sp(this->kth(pos+1),this->root);
			node* tmp=new node(key);
			this->root->rch->lch=tmp;
			tmp->pt=this->root->rch;
			this->root->rch->mt();
			this->root->mt();
		}
		void del(const int& key)
		{	int pos=this->rank(key);
			this->sp(this->kth(pos-1));
			this->sp(this->kth(pos+1),root);
			delete this->root->rch->lch;
			this->root->rch->lch=NULL;
			this->root->rch->mt();
			this->root->mt();
		}
		inline int pre(const int& key){return this->kth(this->rank(key)-1)->key();}
		inline int suc(const int& key){return this->kth(this->rank(key+1))->key();}
		splay()
		{	this->root=new node(-inf);
			this->root->rch=new node(inf);
			this->root->rch->pt=this->root;
			this->root->rch->mt();
			this->root->mt();
		}
};
int main()
{	//freopen("phs.in","r",stdin);
	//freopen("phs.out","w",stdout);
	splay* rt=new splay();
	int t,op,key;
	t=read();
	while(t--)
	{	op=read();key=read();
		if(op==1) rt->insert(key);
		else if(op==2) rt->del(key);
		else if(op==3) printf("%d\n",rt->rank(key)-1);
		else if(op==4) printf("%d\n",rt->kth(key+1)->key());
		else if(op==5) printf("%d\n",rt->pre(key));
		else printf("%d\n",rt->suc(key)); 
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值