关于 FHQ-Treap
查看原帖
关于 FHQ-Treap
762117
快速数论变换楼主2025/7/29 17:38

本人在封装平衡树,用指针写的 FHQ-Treap。但遇到 RE,求助,玄关!

封装代码:

#ifndef BST_HPP
#define BST_HPP
#include<functional>
#include<utility>
#include<random>
#include<ctime>
namespace COB{
	using ll=long long;
	struct null_type{
		null_type()=default;
		null_type(null_type&&)=default;
		null_type(const null_type&)=default;
		bool operator<(const null_type&)const{return false;}
		bool operator<=(const null_type&)const{return true;}
		bool operator>(const null_type&)const{return false;}
		bool operator>=(const null_type&)const{return true;}
		bool operator==(const null_type&)const{return true;}
		bool operator!=(const null_type&)const{return false;}
	};
	template<typename _Key,typename _Val=null_type,typename _Cmp=std::less<_Key>>
	class tree{
		private:
			static std::mt19937 rng;
			struct Node{
				std::pair<_Key,_Val> kkksc03;
				unsigned size,prio;
				Node *ch[2],*prev,*next;
				Node():prio(rng()),size(1),kkksc03{_Key(),_Val()},prev(nullptr),next(nullptr),ch{nullptr,nullptr}{}
				Node(const _Key& k,const _Val& v=_Val()):prio(rng()),size(1),kkksc03{k,v},prev(nullptr),next(nullptr),ch{nullptr,nullptr}{}
				#define key kkksc03.first
				#define val kkksc03.second
			};
			_Cmp cmp;
			Node *root,*head,*tail;
			unsigned size(Node* p)const{return p? p->size:0;}
			std::pair<Node*,Node*> split(unsigned k,Node* p){
				if(!k||!p) return {nullptr,p};
				if(k<=size(p->ch[0])){
					auto l=split(k,p->ch[0]);
					p->ch[0]=l.second;
					update(p);
					return {l.first,p};
				}
				auto r=split(k-size(p->ch[0])-1,p->ch[1]);
				p->ch[1]=r.first;
				update(p);
				return {p,r.second};
			}
			ll update(Node* p){
				p->size=1+size(p->ch[0])+size(p->ch[1]);
				return 0ll;
			}
			Node* merge(Node* x,Node* y){
				if(!x||!y) return (Node*)(((ll)(x))|((ll)(y)));
				return (x->prio<y->prio)?
					(Node*)(((ll)(y->ch[0]=merge(x,y->ch[0])))&update(y)|((ll)y)):
					(Node*)(((ll)(x->ch[1]=merge(x->ch[1],y)))&update(x)|((ll)x));
			}
			unsigned rank(_Key k,Node* p){
				if(!p) return 0;
				if(cmp(k,p->key)) return rank(k,p->ch[0]);
				return size(p->ch[0])+1+rank(k,p->ch[1]);
			}
			Node* first(Node* p){
				if(!p) return nullptr;
				while(p->ch[0]) p=p->ch[0];
				return p;
			}
			Node* last(Node* p){
				if(!p) return nullptr;
				while(p->ch[1]) p=p->ch[1];
				return p;
			}
		public:
			class iterator;
			class const_iterator;
		public:
			class iterator{
				friend class const_iterator;
				private:
					Node* ptr;
				public:
					iterator(Node* ptr=nullptr):ptr(ptr){}
					iterator(const iterator& it):ptr(it.ptr){}
					std::pair<_Key,_Val>& operator*()const{
						return ptr->kkksc03;
					}
					std::pair<_Key,_Val>* operator->()const{
						return &(ptr->kkksc03);
					}
					iterator& operator++(){
						ptr=ptr->next;
						return *this;
					}
					iterator operator++(signed){
						iterator tmp=*this;
						ptr=ptr->next;
						return *tmp;
					}
					iterator& operator--(){
						ptr=ptr->prev;
						return *this;
					}
					iterator operator--(signed){
						iterator tmp=*this;
						ptr=ptr->prev;
						return *tmp;
					}
					bool operator!=(const iterator& oth)const{
						return ptr!=oth.ptr;
					}
					bool operator==(const iterator& oth)const{
						return ptr==oth.ptr;
					}
			};
		public:
			class const_iterator{
				friend class iterator;
				private:
					const Node* ptr;
				public:
					const_iterator(const Node* ptr=nullptr):ptr(ptr){}
					const_iterator(const iterator& it):ptr(it.ptr){}
					const_iterator(const const_iterator& it):ptr(it.ptr){}
					const std::pair<_Key,_Val>& operator*()const{
						return ptr->kkksc03;
					}
					const std::pair<_Key,_Val>* operator->()const{
						return &(ptr->kkksc03);
					}
					const_iterator& operator++(){
						ptr=ptr->next;
						return *this;
					}
					const_iterator operator++(signed){
						iterator tmp=*this;
						ptr=ptr->next;
						return *tmp;
					}
					const_iterator& operator--(){
						ptr=ptr->prev;
						return *this;
					}
					const_iterator operator--(signed){
						iterator tmp=*this;
						ptr=ptr->prev;
						return *tmp;
					}
					const bool operator!=(const const_iterator& oth)const{
						return ptr!=oth.ptr;
					}
					const bool operator==(const const_iterator& oth)const{
						return ptr==oth.ptr;
					}
			};
		public:
			tree(const _Cmp& comp=_Cmp()):root(nullptr),cmp(comp),tail(new Node()){head=tail;}
			tree(const tree& t,const _Cmp& comp=_Cmp()):root(nullptr),cmp(comp),head(nullptr),tail(new Node()){
				for(auto i:t) insert(i.first,i.second);
			}
			~tree(){
				Node* p;
				while(root){
					p=root;
					root=merge(root->ch[0],root->ch[1]);
					delete p;p=nullptr;
				}
				delete tail;
				tail=nullptr;
			}
			void insert(_Key k,_Val v=_Val()){
				auto p=split(rank(k,root),root);
				Node* x=new Node(k,v);
				if(p.first){
					Node* s=last(p.first);
					if(s) s->next=x;
				}
				if(p.second){
					Node* t=last(p.second);
					if(t) t->prev=x;
				}
				root=merge(merge(p.first,x),p.second);
				head=first(root),tail->prev=last(root);
				if(tail->prev) tail->prev->next=tail;
				return;
			}
			bool erase(int k){
				if(empty()) return false;
				auto p1=split(rank(k,root),root);
				auto p2=split(1,p1.second);
				if(p2.first->key!=k) return false;
				if(p2.first){
					Node* x=p2.first;
					if(x->prev) x->prev->next=x->next;
					if(x->next) x->next->prev=x->prev;
					x->prev=x->next=nullptr;
				}
				root=merge(p1.first,p2.second);
				delete p2.first;p2.first=nullptr;
				head=first(root),tail->prev=last(root);
				if(tail->prev) tail->prev->next=tail;
				if(!head) head=tail;
				return true;
			}
			const_iterator find_by_order(unsigned k){
				Node* p=root;
				for(;p;){
					if(k<size(p->ch[0])) p=p->ch[0];
					else if(k==size(p->ch[0])+1) return const_iterator(p);
					else k-=size(p->ch[0])+1,p=p->ch[1];
				}
				return end();
			}
			unsigned order_of_key(_Key k){
				return rank(k,root);
			}
			auto lower_bound(_Key k)const{
				if(!root) return end();
				Node* p=root;
			}
			unsigned size()const{return size(root);}
			bool empty()const{return size(root)==0;}
			iterator begin(){return iterator(head);}
			iterator end(){return iterator(tail);}
			const_iterator begin()const{return iterator(head);}
			const_iterator end()const{return iterator(tail);}
			const_iterator cbegin()const{return iterator(head);}
			const_iterator cend()const{return iterator(tail);}
			
	};
	template<typename _Key,typename _Val,typename _Cmp>
	std::mt19937 tree<_Key,_Val,_Cmp>::rng=std::mt19937((unsigned)time(NULL));
}
#endif

测试代码:

#include<bits/stdc++.h>
#include"priority-queue.hpp"
#include"tree.hpp"
using namespace std;
using namespace COB;
int main(){
	COB::tree<int> tr;
	tr.insert(1);
	tr.insert(2);
	tr.insert(1);
	for(auto i:tr) cout<<i.first<<' ';
	return 0;
}
2025/7/29 17:38
加载中...