【BZOJ】【P3224】【普通平衡树】

传送门:

http://www.lydsy.com/JudgeOnline/problem.php?id=3224

Code:

#include<cstdio>
#include<cstdlib>
#include<climits>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=INT_MAX;
int KEY=12345678;
int rnd(){
	return KEY+=KEY<<2|1;
}
typedef pair<int,int> pii;
struct Treap{
	struct node{
		int val;int key,size,s;
		node *c[2];
		node(int _val,node *C){
			val=_val;key=rand();
			size=1;s=1;
			c[0]=c[1]=C;
		}
		void rz(){
			size=c[0]->size+c[1]->size+s;
		}
	};
	node *root,*Null;
	Treap(){
		Null=new node(0,0);
		Null->size=0;Null->key=INF;Null->val=0;
		Null->c[0]=Null->c[1]=Null;
		root=Null;
	}
	void rot(node *&t,bool d){
		node *p=t->c[d];
		t->c[d]=p->c[!d];
		p->c[!d]=t;
		t->rz();p->rz();
		t=p;
	}
	void _insert(node *&t,int x){
		if(t==Null){
			t=new node(x,Null);
			return ;
		}	
		if(t->val==x){
			t->s++;
			t->size++;
			return;
		}
		bool d=x>t->val;
		_insert(t->c[d],x);
		if(t->c[d]->key<t->key)
			rot(t,d);
		else
		 	t->rz();
	}
	void _Delete(node *&t,int x){
		if(t==Null)return;
		if(t->val==x){
			if(t->s>1){
				t->s--;
				t->size--;
				return;
			}
			bool d=t->c[1]->key<t->c[0]->key;
			if(t->c[d]==Null){
				delete t;
				t=Null;
				return ;
			}
			rot(t,d);
			_Delete(t->c[!d],x);
		}else{
			bool d=x>t->val;
			_Delete(t->c[d],x);
		}
		t->rz();
	}
	int _kth(node *&t,int x){
		int r=t->c[0]->size;
		if(t==Null)return 0;
		else if(x<=r)return _kth(t->c[0],x);
		else if(x>r+t->s)return _kth(t->c[1],x-r-t->s);
		else return t->val;
	}
	int _rank(node *&t,int x){
		int r=t->c[0]->size;
		if(t==Null)return 0;
		else if(x==t->val)return r+1;
		else if(x>t->val)return r+t->s+_rank(t->c[1],x);
		else return _rank(t->c[0],x); 
	}
	void _deb(node *&t){
		printf("val:%d L:%d R:%d\n",t->val,t->c[0]->val,t->c[1]->val);
		//printf("key:%d L:%d R:%d\n",t->key,t->c[0]->key,t->c[1]->key);
		printf("size:%d L:%d R:%d\n",t->size,t->c[0]->size,t->c[1]->size);
		if(t->c[0]!=Null)_deb(t->c[0]);
		if(t->c[1]!=Null)_deb(t->c[1]);
	}
	void deb(){_deb(root);puts("");}
	void insert(int x){_insert(root,x);}
	void del(int x){_Delete(root,x);}
	int kth(int x){return _kth(root,x);}
	int rank(int x){return _rank(root,x);}
	int size(){return root->size;}
	int _prev(node *&t,int x){
		if(t==Null)return INT_MIN;
		if(x<=t->val)return _prev(t->c[0],x);
		return max(t->val,_prev(t->c[1],x));
	}
	int _next(node *&t,int x){
		if(t==Null)return INT_MAX;
		if(x>=t->val)return _next(t->c[1],x);
		return min(t->val,_next(t->c[0],x));
	}
	int prev(int x){
		return _prev(root,x);
	}
	int next(int x){
		return _next(root,x);
	} 
}T;
int main(){
//	freopen("1.txt","r",stdin);
//	freopen("3.txt","w",stdout);
	srand(12121);
	int n,m;
	scanf("%d",&n);m=n;
	while(n--){
		int opt,x;
		scanf("%d",&opt);
		switch(opt){
			case 1:
				scanf("%d",&x);
				T.insert(x);
				break;
			case 2:
				scanf("%d",&x);
				T.del(x);
				break;
			case 3:
				scanf("%d",&x);
				printf("%d\n",T.rank(x));
				break;
			case 4:				
				scanf("%d",&x);
				printf("%d\n",T.kth(x));
				break;
			case 5:
				scanf("%d",&x);
				printf("%d\n",T.prev(x));
				break;
			case 6:
				scanf("%d",&x);
				printf("%d\n",T.next(x));
				break;	
		}
		//T.deb();
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值