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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章