REWA 请求 DEBUG
查看原帖
REWA 请求 DEBUG
922691
Hisy楼主2024/7/2 09:45
#include<bits/stdc++.h>
#define red false
#define black true
using namespace std;
template<typename key_type,typename value_type>
class red_black_tree{
	private:
		class dot_node{
			private:
				pair<key_type,value_type> pos;
				int size;
				bool color;
				dot_node *prev_link;
				dot_node *next_link;
				dot_node *pointer;
			public:
				dot_node(void):pos({key_type(),value_type()}),size(0),color(black),prev_link(nullptr),next_link(nullptr),pointer(nullptr){}; 
				dot_node(pair<key_type,value_type> _pos,int _size,bool _color,dot_node *_prev_link = nullptr,dot_node *_next_link=nullptr,dot_node *_pre=nullptr):pos(_pos),size(_size),color(_color),prev_link(_prev_link),next_link(_next_link),pointer(_pre){};
				dot_node(dot_node *tmp):pos(tmp->pos),size(tmp->size),color(tmp->color),prev_link(tmp->prev_link),next_link(tmp->next_link),pointer(tmp->pointer){};
				dot_node*& get_prev_link(void){
					return prev_link; 
				};
				dot_node*& get_next_link(void){
					return next_link;
				};
				dot_node*& get_pre(void){
					return pointer;
				};
				key_type& get_data(void){
					return pos.first;
				};
				value_type& get_info(void){
					return pos.second;
				};
				pair<key_type,value_type>* get_pair(void){
					return &pos;
				};
				bool get_color(void)const{
					return color;
				};
				int& get_size(void){
					return size;
				};
				void set_prev_link(dot_node*& tmp){
					prev_link=tmp;
				};
				void set_next_link(dot_node*& tmp){
					next_link=tmp;
				};
				void set_pre(dot_node*& tmp){
					pointer=tmp;
				};
				void set_data(key_type tmp){
					pos.first=tmp;
				};
				void set_info(value_type tmp){
					pos.second=tmp;
				};
				void set_color(bool tmp){
					color=tmp;
				};
		};
		bool color(dot_node *node){
			if(node==pointers){
				return true;
			}else{
				return node->get_color();
			};
		};
		void set_color(dot_node *node,bool col){
			node->set_color(col);
		};
		dot_node *&pointer(dot_node *node){
			return node->get_pre();
		};
		dot_node *&prev_link(dot_node *node){
			return node->get_prev_link();
		};
		dot_node *&next_link(dot_node *node){
			return node->get_next_link();
		};
		void LRotate(dot_node *first){
			dot_node *tmp=next_link(first); 
			first->set_next_link(prev_link(tmp));
			if(prev_link(tmp)!=pointers){
				prev_link(tmp)->set_pre(first);
			};
			tmp->set_pre(pointer(first));
			if(pointer(first)==pointers){
				root=tmp;
			}else{
				if(prev_link(pointer(first))==first){
					pointer(first)->set_prev_link(tmp);
				}else{
					pointer(first)->set_next_link(tmp);
				};
			};
			tmp->set_prev_link(first);
			first->set_pre(tmp);
			first->get_size()=1;
			if(first->get_prev_link()!=pointers){
				first->get_size()+=first->get_prev_link()->get_size();
			};
			if(first->get_next_link()!=pointers){
				first->get_size()+=first->get_next_link()->get_size(); 
			};
			tmp->get_size()=first->get_size()+1;
			if(tmp->get_next_link()!=pointers){
				tmp->get_size()+=tmp->get_next_link()->get_size();
			};
		};
		void RRotate(dot_node *first){
			dot_node *tmp=prev_link(first);
			first->set_prev_link(next_link(tmp));
			if(next_link(tmp)!=pointers){
				next_link(tmp)->set_pre(first);
			};
			tmp->set_pre(pointer(first));
			if(pointer(first)==pointers){
				root=tmp;
			}else{
				if(next_link(pointer(first))==first){
					pointer(first)->set_next_link(tmp);
				}else{
					pointer(first)->set_prev_link(tmp);
				};
			};
			tmp->set_next_link(first);
			first->set_pre(tmp);
			first->get_size()=1;
			if(first->get_prev_link()!=pointers){
				first->get_size()+=first->get_prev_link()->get_size();
			};
			if(first->get_next_link()!=pointers){
				first->get_size()+=first->get_next_link()->get_size(); 
			};
			tmp->get_size()=first->get_size()+1;
			if(tmp->get_prev_link()!=pointers){
				tmp->get_size()+=tmp->get_prev_link()->get_size();
			};
		};
		void transplant(dot_node *use,dot_node *val){
			if(pointer(use)==pointers){
				root=val;
			}else if(use==prev_link(pointer(use))){
				pointer(use)->set_prev_link(val);
			}else{
				pointer(use)->set_next_link(val);
			};
			val->set_pre(pointer(use));
		};
		dot_node *minimum(dot_node *first){
			if(first==pointers){
				return first;
			};
			while(prev_link(first)!=pointers){
				--first->get_size();
				first=prev_link(first);
			};
			return first;
		};
		dot_node *maximum(dot_node *first){
			if(first==pointers){
				return first;
			};
			while(next_link(first)!=pointers){
				first=next_link(first); 
			};
			return first; 
		};
		dot_node *prev_link_node(dot_node *first){
			dot_node *tmp=first;
			if(tmp->get_prev_link()==pointers){
				while(tmp->get_pre()!=pointers&&tmp->get_pre()->get_prev_link()==tmp){
					tmp=tmp->get_pre();
				};
				tmp=tmp->get_pre();
			}else{
				tmp=tmp->get_prev_link();
				while(tmp->get_next_link()!=pointers){
					tmp=tmp->get_next_link();
				};
			};
			return tmp;
		};
		dot_node *next_link_node(dot_node *first){
			dot_node *tmp=first;
			if(tmp->get_next_link()==pointers){
				while(tmp->get_pre()!=pointers&&tmp->get_pre()->get_next_link()==tmp){
					tmp=tmp->get_pre();
				};
				tmp=tmp->get_pre();
			}else{
				tmp=tmp->get_next_link();
				while(tmp->get_prev_link()!=pointers){
					tmp=tmp->get_prev_link();
				};
			};
			return tmp; 
		};
	public:
		dot_node *root;
		dot_node *pointers; 
		red_black_tree(void){
			pointers=new dot_node({-1,-1},0,black,pointers,pointers,pointers);
			root=pointers;
		};
		class iterator{
			private:
				dot_node *_node;
			public:
				dot_node* get_node(void){
					return _node;
				};
				iterator &operator++(void){
					_node=_node->next_link_node();
					return *this;
				};
				iterator &operator--(void){
					_node=_node->prev_link_node();
					return *this;
				};
				iterator &operator=(iterator compare1){
					_node=compare1._node;
					return *this;
				};
				friend bool operator==(iterator compare1,iterator compare2){
					return compare1.get_node()==compare2.get_node();
				};
				friend bool operator!=(iterator compare1,iterator compare2){
					return compare1.get_node()!=compare2.get_node();
				};
				pair<key_type,value_type> *operator->(void){
					return _node->get_pair();
				}; 
				iterator(dot_node *__node=nullptr):_node(__node){};
				iterator(const iterator &iter):_node(iter._node){};
		}; 
		dot_node *find(dot_node *first,key_type key){
			dot_node *tmp=first;
			while(tmp!=pointers){
				if(tmp->get_data()>key){
					tmp=tmp->get_prev_link();
				}else if(tmp->get_data()<key){
					tmp=tmp->get_next_link();
				}else{
					break;
				};
			};
			return tmp;
		};
		dot_node *lower_found(key_type key){
			dot_node *parent=pointers;
			dot_node *current=root;
			dot_node *tmp=pointers;
			while(current!=pointers){
				if(current->get_data()>key){
					parent=current;
					current=current->get_prev_link();
				}else if(current->get_data()<key){
					parent=current;
					current=current->get_next_link();
				}else{
					tmp=prev_link_node(current);
					break;
				};
			};
			if(current->get_data()==key){
				while(tmp->get_data()==key){
					tmp=prev_link_node(tmp);
				};
				return tmp;
			};
			if(parent->get_data()>key){
				return prev_link_node(parent);
			}else{
				return parent;
			};
		};
		dot_node *upper_found(key_type key){
			dot_node *parent=pointers;
			dot_node *current=root;
			dot_node *tmp=pointers;
			while(current!=pointers){
				if(current->get_data()>key){
					parent=current;
					current=current->get_prev_link();
				}else if(current->get_data()<key){
					parent=current;
					current=current->get_next_link();
				}else{
					tmp=next_link_node(current);
					break;
				};
			};
			if(current->get_data()==key){
				while(tmp->get_data()==key){
					tmp=next_link_node(tmp);
				};
				return tmp;
			};
			if(parent->get_data()<key){
				return next_link_node(parent);
			}else{
				return parent;
			};
		};
		void insert(pair<key_type,value_type> pos){
			dot_node *second=pointers;
			dot_node *first=root;
			dot_node *third=new dot_node(pos,1,red,pointers,pointers,pointers);
			while(first!=pointers){
				second=first;
				++first->get_size();
				if(pos.first < first->get_data()){
					first=prev_link(first);
				}else{
					first=next_link(first);
				};
			};
			third->set_pre(second);
			if(second==pointers){
				root=third;
			}else if(third->get_data()<second->get_data()){
				second->set_prev_link(third);
			}else{
				second->set_next_link(third);
			};
			third->set_prev_link(pointers);
			third->set_next_link(pointers);
			third->set_color(red);
			after_insert(third);
		};
		void after_insert(dot_node *third){
			while(color(third->get_pre())==red){
				if(pointer(third)==prev_link(pointer(pointer(third)))){
					dot_node *second=next_link(pointer(pointer(third)));
					if(color(second)==red){
						pointer(third)->set_color(black);
						second->set_color(black);
						pointer(pointer(third))->set_color(red);
						third=pointer(pointer(third));
						continue;
					};
					if(third==next_link(pointer(third))){
						third=pointer(third);
						LRotate(third);
					};
					pointer(third)->set_color(black);
					pointer(pointer(third))->set_color(red);
					RRotate(pointer(pointer(third)));
				}else{
					dot_node *second=prev_link(pointer(pointer(third)));
					if(color(second)==red){
						pointer(third)->set_color(black);
						second->set_color(black);
						pointer(pointer(third))->set_color(red);
						third=pointer(pointer(third));
						continue;
					};
					if(third==prev_link(pointer(third))){
						third=pointer(third);
						RRotate(third);
					};
					pointer(third)->set_color(black);
					pointer(pointer(third))->set_color(red);
					LRotate(pointer(pointer(third)));
				};
			};
			root->set_color(black);
		};
		bool erase(dot_node *third){
			dot_node *second=third;
			int yoc=color(second);
			dot_node *first=third;
			if(prev_link(third)==pointers){
				first=next_link(third);
				transplant(third,next_link(third));
			}else if(next_link(third)==pointers){
				first=prev_link(third);
				transplant(third,prev_link(third));
			}else{
				second=minimum(next_link(third));
				yoc=color(second);
				first=next_link(second);
				if(pointer(second)==third){
					first->set_pre(second);
				}else{
					transplant(second,next_link(second));
					second->set_next_link(next_link(third));
					next_link(second)->set_pre(second);
				};
				transplant(third,second);
				second->get_size()=third->get_size();
				second->set_prev_link(prev_link(third));
				prev_link(second)->set_pre(second);
				second->set_color(color(third));
			};
			delete third;
			if(yoc==black){
				after_deletes(first);
			};
			return true; 
		};
		bool erase(key_type val){
			dot_node *tmp=this->root;
			while(tmp!=pointers){
				--tmp->get_size();
				if(tmp->get_data()>val){
					tmp=tmp->get_prev_link();
				}else if(tmp->get_data()<val){
					tmp=tmp->get_next_link();
				}else{
					break;
				};
			};
			if(tmp==pointers){
				return false;
			}else{
				return erase(tmp);
			};
		};
		void after_deletes(dot_node *first){
			while(first!=root&&color(first)==black){
				if(prev_link(pointer(first))==first){
					dot_node *plate=next_link(pointer(first));
					if(color(plate)==red){
						plate->set_color(black);
						pointer(first)->set_color(red);
						LRotate(pointer(first));
						plate=next_link(pointer(first));
					};
					if(color(prev_link(plate))==black&&color(next_link(plate))==black){
						plate->set_color(red);
						first=pointer(first);
					}else{
						if(color(next_link(plate))==black){
							prev_link(plate)->set_color(black);
							plate->set_color(red);
							RRotate(plate);
							plate=next_link(pointer(first));
						};
						plate->set_color(color(pointer(first)));
						pointer(first)->set_color(black);
						next_link(plate)->set_color(black);
						LRotate(pointer(first));
						first=root;
					}                   
				}else{
					dot_node *plate=prev_link(pointer(first));
					if(color(plate)==red){
						plate->set_color(black);
						pointer(first)->set_color(red);
						RRotate(pointer(first));
						plate=prev_link(pointer(first));
					};
					if(color(prev_link(plate))==black&&color(next_link(plate))==black){
						plate->set_color(red);
						first=pointer(first);
					}else{
						if(color(prev_link(plate))==black){
							next_link(plate)->set_color(black);
							plate->set_color(red);
							LRotate(plate);
							plate=prev_link(pointer(first));
						};
						plate->set_color(color(pointer(first)));
						pointer(first)->set_color(black);
						prev_link(plate)->set_color(black);
						RRotate(pointer(first));
						first=root;
					};
				};
			};
			first->set_color(black);
		};
		dot_node *find_sort(int rank,dot_node *pos){
			if(pos->get_prev_link()==pointers){
				if(rank==1){
					return pos;
				}else{
					return find_sort(rank-1,pos->get_next_link());
				};
			}else{
				if(pos->get_prev_link()->get_size()==rank-1){
					return pos;
				}else if(pos->get_prev_link()->get_size()>=rank){
					return find_sort(rank,pos->get_prev_link());
				}else{
					return find_sort(rank-pos->get_prev_link()->get_size()-1,pos->get_next_link());
				};
			};
		};
		int find_rank(key_type val,dot_node *pos){
			if(pos==pointers){
				return 1;
			}else if(pos->get_data()>=val){
				return find_rank(val,pos->get_prev_link());
			}else{
				return(1+(pos->get_prev_link()?pos->get_prev_link()->get_size():0)+find_rank(val,pos->get_next_link()));
			};
		};
};		
int main(int argc,char **argv){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	red_black_tree<int,int> *set=new red_black_tree<int,int>();
	int length,action,last=0,answer=0;
	cin>>length>>action;
	set->insert({1<<30,1});
	set->insert({-(1<<30),1});
	while(length--){
		int got;
		cin>>got;
		set->insert({got,1});
	};
	while(action--){
		int pos,num;
		cin>>pos>>num;
		num^=last;
		if(pos==1){
			set->insert({num,1});
		}else if(pos==2){
			set->erase(num);
		}else if(pos==3){
			answer^=last=set->find_rank(num,set->root);
		}else if(pos==4){
			answer^=last=set->find_sort(num,set->root)->get_data();
		}else if(pos==5){
			answer^=last=set->lower_found(num)->get_data();
		}else if(pos==6){
			answer^=last=set->upper_found(num)->get_data();
		};
	};
	cout<<answer;
	return 0;
};

WA on Subtask 1,2,4,11,12,13,14\color{red}{\texttt{WA on Subtask 1,2,4,11,12,13,14}}

RE on Subtask 5,10,15,18,19,20,21,22,23\color{purple}{\texttt{RE on Subtask 5,10,15,18,19,20,21,22,23}}

2024/7/2 09:45
加载中...