treap oi-wiki写法 0分RE+WA求调
查看原帖
treap oi-wiki写法 0分RE+WA求调
381949
Federico2903楼主2023/2/26 17:45
#include<bits/stdc++.h>
using namespace std;
struct node{
	int val,rk,rep,siz;
	node* s[2];
	node(int val): val(val),rep(1),siz(1){
		s[0]=s[1]=nullptr;
		rk=rand();
	}
	void upd_siz(){
		siz=rep;
		if(s[0]!=nullptr)siz+=s[0]->siz;
		if(s[1]!=nullptr)siz+=s[1]->siz;
	}
};
struct treap{
	node* root;
	int q_prev_tmp,q_nxt_tmp;
	void left_rot(node* &cur){	
		node* tmp=cur->s[1];
		cur->s[1]=tmp->s[0];
		tmp->s[0]=cur;//左旋操作
		tmp->upd_siz();cur->upd_siz();
	}
	void right_rot(node* &cur){
		node* tmp=cur->s[0];
		cur->s[0]=tmp->s[1];
		tmp->s[1]=cur;//右旋操作
		tmp->upd_siz();cur->upd_siz();
	}
	void insert(node* &cur,int val){
		if(cur==nullptr){
			cur=new node(val);return;
		}
		else if(cur->val==val){
			cur->rep++;cur->siz++;
		}
		else if(cur->val<val){
			insert(cur->s[1],val);
			if(cur->s[1]->rk<cur->rk)left_rot(cur);
			cur->upd_siz();
		}
		else{
			insert(cur->s[0],val);
			if(cur->s[0]->rk<cur->rk)right_rot(cur);
			cur->upd_siz();
		}
	}
	void del(node* &cur,int val){
		if(cur->val<val){del(cur->s[1],val);cur->upd_siz();}
		else if(cur->val>val){del(cur->s[0],val);cur->upd_siz();}
		else{
			if(cur->rep>1){cur->rep--;cur->siz--;return;}
			node *tmp=cur;
			if(cur->s[0]!=nullptr){
				if(cur->s[1]!=nullptr){
					//左右都有
					if(cur->s[0]->rk<cur->s[1]->rk){right_rot(cur);del(cur->s[1],val);}
					else{left_rot(cur);del(cur->s[1],val);}
					cur->upd_siz();
				}
				else{
					//只有左
					cur=tmp->s[0];delete tmp;return;
				}
			}
			else{
				if(cur->s[1]!=nullptr){
					//只有右
					cur=tmp->s[1];delete tmp;return;
				}
				else{
					//左右都没
					delete cur;cur=nullptr;return;
				}
			}
		}
	}
	int query_rank(node *cur,int val){
		int less_size=cur->s[0]==nullptr?0:cur->s[0]->siz;
		if(cur->val==val)return less_size+1;
		else if(cur->val<val){
			if(cur->s[1]!=nullptr)return less_size+cur->rep+query_rank(cur->s[1],val);
			else return cur->siz+1;
		}
		else{
			if(cur->s[0]!=nullptr)return query_rank(cur->s[0],val);
			else return 1;
		}
	}
	int query_val(node *cur,int rk){
		int less_size=cur->s[0]==nullptr?0:cur->s[0]->siz;
		if(rk<=less_size){
			return query_val(cur->s[0],rk);
		}
		else if(rk<=less_size+cur->rep){
			return cur->val;
		}
		else{
			return query_val(cur->s[1],rk-less_size-cur->rep);
		}
	}
	int query_prev(node *cur,int val){
		if(cur->val>=val){
			if(cur->s[0]!=nullptr){
				return query_prev(cur->s[0],val);
			}
		}
		else{
			q_prev_tmp=cur->val;
			if(cur->s[1]!=nullptr){
				query_prev(cur->s[1],val);
			}
			return q_prev_tmp;
		}
		return -1;
	}
	int query_nxt(node *cur,int val){
		if(cur->val<=val){
			if(cur->s[1]!=nullptr){
				return query_nxt(cur->s[1],val);
			}
		}
		else{
			q_nxt_tmp=cur->val;
			if(cur->s[0]!=nullptr){
				query_nxt(cur->s[0],val);
			}
			return q_nxt_tmp;
		}
		return -1;
	}
}tree;
void init(){
	srand(time(0));
}
int n,opt,x;
int main() {
	init();
	cin >> n;
	for(int i=0;i<n;i++){
		cin >> opt >> x;
		switch(opt){
		case 1:
			tree.insert(tree.root,x);
			break;
		case 2:
			tree.del(tree.root,x);
			break;
		case 3:
			cout << tree.query_rank(tree.root,x) << endl;
			break;
		case 4:
			cout << tree.query_val(tree.root,x) << endl;
			break;
		case 5:
			cout << tree.query_prev(tree.root,x) << endl;
			break;
		case 6:
			cout << tree.query_nxt(tree.root,x) << endl;
			break;
		}
	}
	return 0;
}
2023/2/26 17:45
加载中...