本人在封装平衡树,用指针写的 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;
}