aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp/dsa/SplayTree.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'meowpp/dsa/SplayTree.hpp')
-rw-r--r--meowpp/dsa/SplayTree.hpp505
1 files changed, 505 insertions, 0 deletions
diff --git a/meowpp/dsa/SplayTree.hpp b/meowpp/dsa/SplayTree.hpp
new file mode 100644
index 0000000..835664f
--- /dev/null
+++ b/meowpp/dsa/SplayTree.hpp
@@ -0,0 +1,505 @@
+
+namespace meow{
+ template<class Key, class Value>
+ inline SplayTree<Key, Value>::Node::Node(Key const& __key,
+ Value const& __value):
+ _key(__key),
+ _keyOffset(0),
+ _value(__value),
+ _size(1),
+ _parent(NULL),
+ _lChild(NULL),
+ _rChild(NULL){ }
+ //
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::offsetAdd(Node* __node,
+ Key const& __delta) const{
+ __node->_key = __node->_key + __delta;
+ __node->_keyOffset = __node->_keyOffset + __delta;
+ }
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::sizeUpdate(Node* __node) const{
+ __node->_size = 1;
+ if(__node->_lChild != NULL) __node->_size += __node->_lChild->_size;
+ if(__node->_rChild != NULL) __node->_size += __node->_rChild->_size;
+ }
+ template<class Key, class Value>
+ inline void
+ SplayTree<Key, Value>::offsetDown(Node* __node) const{
+ if(__node->_lChild != NULL) offsetAdd(__node->_lChild, __node->_keyOffset);
+ if(__node->_rChild != NULL) offsetAdd(__node->_rChild, __node->_keyOffset);
+ __node->_keyOffset = 0;
+ }
+ //
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::connectLChild(Node* __parent,
+ Node* __child) const{
+ if(__parent != NULL) __parent->_lChild = __child;
+ if(__child != NULL) __child ->_parent = __parent;
+ }
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::connectRChild(Node* __parent,
+ Node* __child) const{
+ if(__parent != NULL) __parent->_rChild = __child;
+ if(__child != NULL) __child ->_parent = __parent;
+ }
+ //
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Node*
+ SplayTree<Key, Value>::clear(Node* __node){
+ if(__node != NULL){
+ clear(__node->_lChild);
+ clear(__node->_rChild);
+ delete __node;
+ }
+ return NULL;
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Node* SplayTree<Key, Value>::dup(Node* __node){
+ if(__node == NULL){
+ return NULL;
+ }
+ Node* node = Node(__node->_key, __node->_value);
+ connectLChild(node, dup(__node->_lChild));
+ connectRChild(node, dup(__node->_rChild));
+ return node;
+ }
+ //
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::rotate(Node* __parent,
+ Node* __child) const{
+ if(__parent->_lChild == __child){
+ connectLChild(__parent, __child->_rChild);
+ connectRChild(__child , __parent);
+ }else{
+ connectRChild(__parent, __child->_lChild);
+ connectLChild(__child , __parent);
+ }
+ sizeUpdate(__parent);
+ sizeUpdate(__child );
+ }
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::rotate(Node* __grand,
+ Node* __parent,
+ Node* __child) const{
+ if(__grand->_lChild == __parent){
+ if(__parent->_lChild == __child){
+ connectLChild(__grand , __parent->_rChild);
+ connectLChild(__parent, __child ->_rChild);
+ connectRChild(__child , __parent);
+ connectRChild(__parent, __grand );
+ }else{
+ connectRChild(__parent, __child->_lChild);
+ connectLChild(__grand , __child->_rChild);
+ connectLChild(__child, __parent);
+ connectRChild(__child, __grand );
+ }
+ }else if(__grand->_rChild == __parent){
+ if(__parent->_rChild == __child){
+ connectRChild(__grand , __parent->_lChild);
+ connectRChild(__parent, __child ->_lChild);
+ connectLChild(__child , __parent);
+ connectLChild(__parent, __grand );
+ }else{
+ connectRChild(__grand , __child->_lChild);
+ connectLChild(__parent, __child->_rChild);
+ connectLChild(__child, __grand );
+ connectRChild(__child, __parent);
+ }
+ }
+ sizeUpdate(__grand );
+ sizeUpdate(__parent);
+ sizeUpdate(__child );
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Node* SplayTree<Key, Value>::splay(Node* __node) const{
+ if(__node == NULL){
+ return NULL;
+ }
+ for(Node *parent, *grand, *child = __node; child->_parent != NULL; ){
+ parent = child ->_parent;
+ grand = parent->_parent;
+ if(grand == NULL){
+ rotate(parent, child);
+ break;
+ }else{
+ Node* g_grand = grand->_parent;
+ rotate(grand, parent, child);
+ if(g_grand == NULL){
+ break;
+ }
+ if(g_grand->_lChild == grand) connectLChild(g_grand, child);
+ else connectRChild(g_grand, child);
+ }
+ }
+ return __node;
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Node* SplayTree<Key, Value>::findKey(Node* __node,
+ Key const& __key) const{
+ Node* ret = __node;
+ for(Key offset_sum = 0; __node != NULL; offset_sum += ret->_keyOffset){
+ offsetDown(__node);
+ ret = __node;
+ if(!(__key < offset_sum + __node->_key)){
+ if(!(offset_sum + __node->_key< __key)){
+ break;
+ }
+ __node = __node->_rChild;
+ }else{
+ __node = __node->_lChild;
+ }
+ }
+ return ret;
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Node* SplayTree<Key, Value>::findMinMax(Node* __node,
+ bool minimum) const{
+ Node* ret = __node;
+ while(__node != NULL){
+ offsetDown(__node);
+ ret = __node;
+ __node = (minimum ? __node->_lChild : __node->_rChild);
+ }
+ return ret;
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Node* SplayTree<Key, Value>::findOrder(Node* __node,
+ size_t __order) const{
+ Node* ret = __node;
+ while(__node != NULL){
+ offsetDown(__node);
+ ret = __node;
+ size_t ord = 1 + (__node->_lChild == NULL ? 0 : __node->_lChild->_size);
+ if(ord == __order){
+ return ret;
+ }else if(ord < __order){
+ __node = __node->_rChild;
+ __order -= ord;
+ }else{
+ __node = __node->_lChild;
+ }
+ }
+ return ret;
+ }
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::split(Node* __root,
+ Node** __left, Node** __right){
+ if(__root == NULL){
+ *__left = NULL;
+ *__right = NULL;
+ return ;
+ }
+ offsetDown(__root);
+ *__left = __root;
+ *__right = __root->_rChild;
+ if(*__right != NULL){
+ (*__left )->_rChild = NULL;
+ (*__right)->_parent = NULL;
+ sizeUpdate(*__left);
+ }
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Node* SplayTree<Key, Value>::merge(Node* __left, Node* __right){
+ if(__left == NULL) return __right;
+ if(__right == NULL) return __left ;
+ offsetDown(__left);
+ connectRChild(__left, __right);
+ sizeUpdate(__left);
+ return __left;
+ }
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::print(Node* __now, int __depth) const{
+ if(__now == NULL) return ;
+ printf("%*s [%llX]:\tParent=%llX Left=%llX Right=%llX\n",
+ __depth * 2, "",
+ (long long unsigned)__now,
+ (long long unsigned)__now->_parent,
+ (long long unsigned)__now->_lChild,
+ (long long unsigned)__now->_rChild);
+ print(__now->_lChild, __depth + 1);
+ print(__now->_rChild, __depth + 1);
+ }
+ //
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::Element::reset(Node* __node){
+ _node = __node;
+ delete _entry;
+ if(__node == NULL){
+ _entry = NULL;
+ }else{
+ _entry = new Entry(__node->_key, __node->_value);
+ }
+ }
+ template<class Key, class Value>
+ inline SplayTree<Key, Value>::Element::Element():
+ _entry(NULL),
+ _node(NULL){ }
+ template<class Key, class Value>
+ inline SplayTree<Key, Value>::Element::Element(Node* __node):
+ _entry(NULL),
+ _node(NULL){ reset(__node); }
+ template<class Key, class Value>
+ inline SplayTree<Key, Value>::Element::Element(Element const& __element2):
+ _entry(NULL),
+ _node(NULL){ reset(__element2._node); }
+ template<class Key, class Value>
+ inline SplayTree<Key, Value>::Element::~Element(){ delete _entry; }
+ //
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element&
+ SplayTree<Key, Value>::Element::operator=(Element const& __e2){
+ reset(__e2._node);
+ return *this;
+ }
+ //
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element::Entry* SplayTree<Key, Value>::Element::operator->(){ return _entry; }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element::Entry& SplayTree<Key, Value>::Element::operator*(){ return *_entry; }
+ //
+ template<class Key, class Value>
+ inline bool
+ SplayTree<Key, Value>::Element::operator==(Element const& __e2) const{
+ return (_node == __e2._node);
+ }
+ template<class Key, class Value>
+ inline bool
+ SplayTree<Key, Value>::Element::operator!=(Element const& __e2) const{
+ return (_node != __e2._node);
+ }
+ //
+ template<class Key, class Value>
+ inline SplayTree<Key, Value>::SplayTree():
+ _root(NULL){ }
+ template<class Key, class Value>
+ inline SplayTree<Key, Value>::SplayTree(SplayTree const& __tree2):
+ _root(NULL){
+ _root = dup(__tree2._root);
+ }
+ template<class Key, class Value>
+ inline SplayTree<Key, Value>::~SplayTree(){
+ clear(_root);
+ }
+ template<class Key, class Value>
+ inline SplayTree<Key, Value>& SplayTree<Key, Value>::operator=(SplayTree const& __tree2){
+ clear(_root);
+ _root = dup(__tree2._root);
+ return *this;
+ }
+ //
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element SplayTree<Key, Value>::lowerBound(Key const& __key) const{
+ SplayTree* me = (SplayTree*)this;
+ me->_root = splay(findKey(me->_root, __key));
+ me->_root->_parent = NULL;
+ if(_root == NULL || !(_root->_key < __key)){
+ return Element(_root);
+ }
+ if(_root->_rChild == NULL){
+ return NULL;
+ }
+ me->_root = splay(findMinMax(me->_root->_rChild, true));
+ me->_root->_parent = NULL;
+ return Element(_root);
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element SplayTree<Key, Value>::upperBound(Key const& __key) const{
+ SplayTree* me = (SplayTree*)this;
+ me->_root = splay(findKey(me->_root, __key));
+ me->_root->_parent = NULL;
+ if(_root == NULL || __key < _root->_key){
+ return Element(_root);
+ }
+ if(_root->_rChild == NULL){
+ return NULL;
+ }
+ me->_root = splay(findMinMax(me->_root->_rChild, true));
+ me->_root->_parent = NULL;
+ return Element(_root);
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element SplayTree<Key, Value>::rLowerBound(Key const& __key) const{
+ SplayTree* me = (SplayTree*)this;
+ me->_root = splay(findKey(me->_root, __key));
+ me->_root->_parent = NULL;
+ if(_root == NULL || !(__key < _root->_key)){
+ return Element(_root);
+ }
+ if(_root->_lChild == NULL){
+ return NULL;
+ }
+ me->_root = splay(findMinMax(me->_root->_lChild, false));
+ me->_root->_parent = NULL;
+ return Element(_root);
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element SplayTree<Key, Value>::rUpperBound(Key const& __key) const{
+ SplayTree* me = (SplayTree*)this;
+ me->_root = splay(findKey(me->_root, __key));
+ me->_root->_parent = NULL;
+ if(_root == NULL || _root->_key < __key){
+ return Element(_root);
+ }
+ if(_root->_lChild == NULL){
+ return NULL;
+ }
+ me->_root = splay(findMinMax(me->_root->_lChild, false));
+ me->_root->_parent = NULL;
+ return Element(_root);
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element SplayTree<Key, Value>::find(Key const& __key) const{
+ SplayTree* me = (SplayTree*)this;
+ me->_root = splay(findKey(me->_root, __key));
+ me->_root->_parent = NULL;
+ if(_root != NULL && _root->_key == __key){
+ return Element(_root);
+ }
+ return Element(NULL);
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element SplayTree<Key, Value>::order(size_t __order) const{
+ SplayTree* me = (SplayTree*)this;
+ me->_root = splay(findOrder(me->_root, __order + 1));
+ me->_root->_parent = NULL;
+ return Element(_root);
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element SplayTree<Key, Value>::first() const{
+ SplayTree* me = (SplayTree*)this;
+ me->_root = splay(findMinMax(me->_root, true));
+ me->_root->_parent = NULL;
+ return Element(_root);
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element SplayTree<Key, Value>::last() const{
+ SplayTree* me = (SplayTree*)this;
+ me->_root = splay(findMinMax(me->_root, false));
+ me->_root->_parent = NULL;
+ return Element(_root);
+ }
+ template<class Key, class Value>
+ inline typename SplayTree<Key, Value>::Element SplayTree<Key, Value>::end() const{ return Element(NULL); }
+ template<class Key, class Value>
+ inline size_t SplayTree<Key, Value>::size() const{
+ return (_root == NULL ? 0 : _root->_size);
+ }
+ template<class Key, class Value>
+ inline bool SplayTree<Key, Value>::empty() const{ return (size() == 0); }
+ //
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::clear(){
+ clear(_root);
+ _root = NULL;
+ }
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::keyOffset(Key const& __delta){
+ if(_root != NULL){
+ offsetAdd(_root, __delta);
+ }
+ }
+ template<class Key, class Value>
+ inline bool SplayTree<Key, Value>::insert(Key const& __key,
+ Value const& __value){
+ if(_root == NULL){
+ _root = new Node(__key, __value);
+ return true;
+ }
+ Node* parent = findKey(_root, __key);
+ Node* new_node;
+ if(parent->_key < __key){
+ connectRChild(parent, new_node = new Node(__key, __value));
+ }else if(__key < parent->_key){
+ connectLChild(parent, new_node = new Node(__key, __value));
+ }else{
+ _root = splay(parent);
+ _root->_parent = NULL;
+ return false;
+ }
+ _root = splay(new_node);
+ _root->_parent = NULL;
+ return true;
+ }
+ template<class Key, class Value>
+ inline bool SplayTree<Key, Value>::erase(Key const& __key){
+ if(_root == NULL){
+ return false;
+ }
+ Node* body = findKey(_root, __key);
+ if(body->_key < __key || __key < body->_key){
+ return false;
+ }
+ Node* ghost;
+ if(body->_rChild == NULL){
+ ghost = body->_lChild;
+ }else{
+ ghost = findMinMax(body->_rChild, true);
+ connectLChild(ghost, body->_lChild);
+ if(ghost != body->_rChild){
+ connectLChild(ghost->_parent, ghost->_lChild);
+ connectLChild(ghost, body->_rChild);
+ }
+ }
+ if(body->_parent != NULL && body->_parent->_lChild == body){
+ connectLChild(body->_parent, ghost);
+ }else{
+ connectRChild(body->_parent, ghost);
+ }
+ _root = splay(ghost != NULL ? ghost : body->_parent);
+ _root->_parent = NULL;
+ return true;
+ }
+ template<class Key, class Value>
+ inline Value& SplayTree<Key, Value>::operator[](Key const& __key){
+ if(find(__key) == end()){
+ insert(__key, Value());
+ }
+ return find(__key)->second;
+ }
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::splitOut(Key const& __upper_bound,
+ SplayTree* __right){
+ __right->clear();
+ rLowerBound(__upper_bound);
+ split(_root, &_root, &(__right->_root));
+ }
+ template<class Key, class Value>
+ inline bool SplayTree<Key, Value>::mergeAfter(SplayTree* __tree2){
+ if(_root == NULL || __tree2->_root == NULL ||
+ last()->first < __tree2->first()->first){
+ _root = merge(_root, __tree2->_root);
+ __tree2->_root = NULL;
+ return true;
+ }
+ return false;
+ }
+ template<class Key, class Value>
+ inline bool SplayTree<Key, Value>::merge(SplayTree* __tree2){
+ if(_root == NULL || __tree2->_root == NULL){
+ _root = merge(_root, __tree2->_root);
+ }else{
+ if(last()->first < __tree2->first()->first){
+ _root = merge(_root, __tree2->_root);
+ __tree2->_root = NULL;
+ }else if(__tree2->last()->first < first()->first){
+ _root = merge(__tree2->_root, _root);
+ }else{
+ return false;
+ }
+ }
+ __tree2->_root = NULL;
+ return true;
+ }
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::print() const{
+ print(_root, 0);
+ }
+ template<class Key, class Value>
+ inline void SplayTree<Key, Value>::moveTo(SplayTree* __tree2){
+ __tree2->clear();
+ __tree2->_root = _root;
+ _root = NULL;
+ }
+}
+