zoukankan      html  css  js  c++  java
  • Splay 模板

    /*
     * by
     * 		skip2004
     *	Splay Tree
     */
     
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <random>
    #include <string>
    #include <cstdio>
    #include <ctime>
    
    namespace Splay{
    	
    	#define ERROR_CHECK(condition,ERROR) if(__builtin_expect(condition,0)) puts(ERROR), exit(0);
    	
    	template<typename _Tp, typename _Cmp = std::less<_Tp>>
    	class Splay_Node;
    	
    	template<typename _Tp, typename _Cmp = std::less<_Tp>>
    	class Splay_Tree;
    	
    	template<typename _Tp, typename _Cmp>
    	class Splay_Node{
    		private:
    			
    			Splay_Node * left_son, * right_son, * father;
    			_Tp value;
    			size_t size;
    			inline void clear();	
    			inline void left_rotate();	
    			inline void right_rotate();
    		public: 
    		
    			inline bool is_left_son() const;
    			inline bool is_right_son() const;
    			inline bool is_root() const;
    			inline void update();
    			inline void rotate();
    			inline _Tp kth_element(size_t k,Splay_Tree<_Tp,_Cmp> * tree);
    			inline size_t get_size() const;
    			inline _Tp get_value() const;
    			inline Splay_Node(_Tp value);
    			inline Splay_Node *& get_left_son();
    			inline Splay_Node *& get_right_son();
    			inline Splay_Node *& get_father();
    	};
    	
    	template<typename _Tp, typename _Cmp>
    	class Splay_Tree
    	{
    		private:
    			const _Cmp& cmp = _Cmp{};
    			Splay_Node<_Tp,_Cmp> * root;
    			inline void insert(Splay_Node<_Tp,_Cmp> * oth);
    		public:
    			
    			inline void splay(Splay_Node<_Tp,_Cmp> * node);
    			inline Splay_Tree(Splay_Node<_Tp,_Cmp> * root = nullptr);
    			inline void insert(_Tp value);
    			inline void erase(_Tp value);
    			inline Splay_Node<_Tp,_Cmp> * lower_bound(_Tp value);
    			inline Splay_Node<_Tp,_Cmp> * upper_bound(_Tp value);
    			inline size_t lower(_Tp value);
    			inline size_t less_than(_Tp value);
    			inline size_t get_rank(_Tp value);
    			inline _Tp kth_element(size_t k);
    			inline size_t size() const;
    			inline bool empty() const;
    			inline _Tp predecessor(_Tp value);
    			inline _Tp successor(_Tp value);	
    	};
    	
    	
    	template<typename _Tp, typename _Cmp>
    		inline void Splay_Node<_Tp,_Cmp>::clear()
    		{
    			if(left_son != nullptr)
    			{
    				this -> left_son -> clear();
    			}
    			if(right_son != nullptr)
    			{
    				this -> right_son -> clear();
    			}
    			delete this;
    		}
    		
    	template<typename _Tp, typename _Cmp>
    		inline bool Splay_Node<_Tp, _Cmp>::is_left_son() const
    		{
    			return this -> father != nullptr && this == father -> left_son;
    		}
    		
    	template<typename _Tp, typename _Cmp>
    		inline bool Splay_Node<_Tp, _Cmp>::is_right_son() const
    		{
    			return this -> father != nullptr && this == father -> right_son;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline bool Splay_Node<_Tp,_Cmp>::is_root() const 
    		{
    			return this -> father == nullptr;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline void Splay_Node<_Tp,_Cmp>::update()
    		{
    			this -> size = 1;
    			if(left_son != nullptr) this -> size += left_son -> size;
    			if(right_son != nullptr) this -> size += right_son -> size;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline void Splay_Node<_Tp,_Cmp>::left_rotate()
    		{
    			ERROR_CHECK(father == nullptr,"No father !");
    			Splay_Node * fa = father, * grand_father = fa -> father;
    			if(grand_father != nullptr)
    			{
    				if(father -> is_left_son())
    					grand_father -> left_son = this;
    				else
    					grand_father -> right_son = this;
    			}
    			fa -> right_son = this -> left_son;
    			this -> left_son = fa;
    			if(fa -> right_son != nullptr)
    				fa -> right_son -> father = fa;
    			fa -> father = this;
    			this -> father = grand_father;
    			fa -> update();
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline void Splay_Node<_Tp,_Cmp>::right_rotate()
    		{
    			ERROR_CHECK(father == nullptr,"No father !");
    			Splay_Node * fa = father, * grand_father = fa -> father;
    			if(grand_father != nullptr)
    			{
    				if(father -> is_left_son())
    					grand_father -> left_son = this;
    				else
    					grand_father -> right_son = this;
    			}
    			fa -> left_son = this -> right_son;
    			this -> right_son = fa;
    			if(fa -> left_son != nullptr)
    				fa -> left_son -> father = fa;
    			fa -> father = this;
    			this -> father = grand_father;
    			fa -> update();
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline void Splay_Node<_Tp,_Cmp>::rotate()
    		{
    			if(this -> is_left_son())
    				right_rotate();
    			else
    				left_rotate();
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline _Tp Splay_Node<_Tp,_Cmp>::kth_element(size_t k,Splay_Tree<_Tp,_Cmp> * tree)
    		{
    			const size_t left_son_size = this -> left_son == nullptr ? 0 : this -> left_son -> size;
    			if(left_son_size >= k) 
    				return this -> left_son -> kth_element(k,tree);
    			if(left_son_size + 1 == k)
    			{
    				tree -> splay(this);
    				return this -> value;
    			}
    			return this -> right_son -> kth_element(k - left_son_size - 1,tree);
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline size_t Splay_Node<_Tp,_Cmp>::get_size() const
    		{
    			return this -> size;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline _Tp Splay_Node<_Tp,_Cmp>::get_value() const
    		{
    			return this -> value;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline Splay_Node<_Tp,_Cmp>::Splay_Node(_Tp value)
    		{
    			left_son = right_son = father = nullptr;
    			this -> value = value, size = 1;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline Splay_Node<_Tp,_Cmp> *& Splay_Node<_Tp,_Cmp>::get_left_son()
    		{
    			return this -> left_son;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline Splay_Node<_Tp,_Cmp> *& Splay_Node<_Tp,_Cmp>::get_right_son()
    		{
    			return this -> right_son;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline Splay_Node<_Tp,_Cmp> *& Splay_Node<_Tp,_Cmp>::get_father()
    		{
    			return this -> father;
    		}
    	
    	
    	template<typename _Tp,typename _Cmp>
    		inline void Splay_Tree<_Tp,_Cmp>::splay(Splay_Node<_Tp,_Cmp> * node)
    		{
    			for(;!node -> is_root();node -> rotate())
    				if(!node -> get_father() -> is_root())
    				{
    					if(node -> is_left_son()  ^ node -> get_father() -> is_left_son())
    						node -> rotate();
    					else
    						node -> get_father() -> rotate();
    				}
    			node -> update();
    			root = node;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline void Splay_Tree<_Tp,_Cmp>::insert(Splay_Node<_Tp,_Cmp> * oth)
    		{
    			if(oth == nullptr)
    				return ;
    			if(root == nullptr)
    				root = oth;
    			else
    			{
    				Splay_Node<_Tp,_Cmp> * now = root;
    				while(true)
    				{
    					if(cmp(oth -> get_value(),now -> get_value()))
    						if(now -> get_left_son() == nullptr)
    						{
    							now -> get_left_son() = oth;
    							oth -> get_father() = now;
    							splay(now -> get_left_son());
    							return ;
    						}
    						else
    							now = now -> get_left_son();
    					else
    						if(now -> get_right_son() == nullptr)
    						{
    							now -> get_right_son() = oth;
    							oth -> get_father() = now;
    							splay(now -> get_right_son());
    							return ;
    						}
    						else
    							now = now -> get_right_son();
    				}
    			}
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline Splay_Tree<_Tp,_Cmp>::Splay_Tree(Splay_Node<_Tp,_Cmp> * root)
    		{
    			this -> root = root;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline void Splay_Tree<_Tp,_Cmp>::insert(_Tp value)
    		{
    			insert(new Splay_Node<_Tp,_Cmp>(value));
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline void Splay_Tree<_Tp,_Cmp>::erase(_Tp value)
    		{
    			Splay_Node<_Tp,_Cmp> * now = root;
    			while(now != nullptr)
    			{
    				if(cmp(now -> get_value(),value))
    					now = now -> get_right_son();
    				else
    					if(cmp(value, now -> get_value()))
    						now = now -> get_left_son();
    					else 
    					{
    						splay(now);
    						if(now -> get_left_son() != nullptr)
    							now -> get_left_son() -> get_father() = nullptr;
    						if(now -> get_right_son() != nullptr)
    							now -> get_right_son() -> get_father() = nullptr;
    						root = now -> get_left_son();
    						insert(now -> get_right_son());
    						return ;
    					}
    			}
    			throw "Error in function : erase";
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline Splay_Node<_Tp,_Cmp> * Splay_Tree<_Tp,_Cmp>::lower_bound(_Tp value)
    		{
    			Splay_Node<_Tp,_Cmp> * now = root, * ans = nullptr;
    			while(now != nullptr)
    			{
    				if(cmp(now -> get_value(),value))
    				{
    					if(!now -> get_right_son())
    					{
    						splay(now);
    						break;
    					}
    					now = now -> get_right_son();
    				}
    				else
    				{
    					ans = now;
    					if(!now -> get_left_son())
    					{
    						splay(now);
    						break; 
    					} 
    					now = now -> get_left_son();
    				}
    			}
    			return ans;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline Splay_Node<_Tp,_Cmp> * Splay_Tree<_Tp,_Cmp>::upper_bound(_Tp value)
    		{
    			Splay_Node<_Tp,_Cmp> * now = root, * ans = nullptr;
    			while(now != nullptr)
    			{
    				if(cmp(value,now -> get_value()))
    				{
    					ans = now;
    					if(!now -> get_left_son())
    					{
    						splay(now);
    						break;
    					}
    					now = now -> get_left_son();
    				}
    				else
    				{
    					if(!now -> get_right_son())
    					{
    						splay(now);
    						break;
    					}
    					now = now -> get_right_son();
    				}
    			}
    			return ans;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline size_t Splay_Tree<_Tp,_Cmp>::lower(_Tp value)
    		{
    			if(root == nullptr)
    				return 0;
    			Splay_Node<_Tp,_Cmp> * node = this -> upper_bound(value);
    			if(node == nullptr)
    				return root -> get_size();
    			splay(node);
    			if(node -> get_left_son() == nullptr)
    				return 0;
    			return node -> get_left_son() -> get_size();
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline size_t Splay_Tree<_Tp,_Cmp>::less_than(_Tp value)
    		{
    			if(root == nullptr)
    				return 0;
    			Splay_Node<_Tp,_Cmp> * node = this -> lower_bound(value);
    			if(node == nullptr)
    				return root -> get_size();
    			splay(node);
    			if(node -> get_left_son() == nullptr)
    				return 0;
    			return node -> get_left_son() -> get_size();
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline size_t Splay_Tree<_Tp,_Cmp>::get_rank(_Tp value)
    		{
    			return less_than(value) + 1;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline _Tp Splay_Tree<_Tp,_Cmp>::kth_element(size_t k)
    		{
    			ERROR_CHECK(root == nullptr,"Error: No element in the Splay Tree. ");
    			ERROR_CHECK(k < 1 || k > this -> size(),"Error: K is out of range !");
    			return root -> kth_element(k,this);
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline size_t Splay_Tree<_Tp,_Cmp>::size() const
    		{
    			if(root == nullptr)
    				return 0;
    			else
    				return root -> get_size();
    		}
    	
    	template<typename _Tp,typename _Cmp>
    		inline bool Splay_Tree<_Tp,_Cmp>::empty() const
    		{
    			return root == nullptr;
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline _Tp Splay_Tree<_Tp,_Cmp>::predecessor(_Tp value)
    		{
    			return kth_element(less_than(value));
    		}
    		
    	template<typename _Tp,typename _Cmp>
    		inline _Tp Splay_Tree<_Tp,_Cmp>::successor(_Tp value)
    		{
    			return kth_element(lower(value) + 1);
    		}
    	
    }
    
    Splay::Splay_Tree<int> tree;
    int x,ch,flag;
    inline int read()
    {
    	while(isspace(ch=getchar())); flag = 0;
    	if(ch == 45) ch = getchar(), flag = 1; x = ch & 15;
    	while(isdigit(ch=getchar())) x = x * 10 + (ch&15);
    	return flag ? - x : x;
    }
    int main()
    {
    	std::ios::sync_with_stdio(false), std::cin.tie(0);
    	std::ios::sync_with_stdio(false), std::cin.tie(0);
        int n = read();
        for(int i = 1; i <= n; ++i)
        {
            int opt = read(), x = read();
            switch(opt)
            {
                case 1:
                    {
                        tree.insert(x);
                        break;
                    }
                case 2:
                    {
                        tree.erase(x);
                        break;
                    }
                case 3:
                    {
                        std::cout << tree.get_rank(x) << '
    ' ;
                        break;
                    }
                case 4:
                    {
                        std::cout << tree.kth_element(x) << '
    ';
                        break;
                    }
                case 5:
                    {
                        std::cout << tree.predecessor(x) << '
    ';
                        break;
                    } 
                case 6:
                    {
                        std::cout << tree.successor(x)	<< '
    ';
                        break;
                    }
            }
        }
    }
    
  • 相关阅读:
    Topshelf 搭建 Windows 服务
    Xamarin.Android 6.0以后开启权限方法
    使用ADB安装apk安装包
    C# 杀掉系统中的进程
    C# 使用CefSharp嵌入网站
    .Net Core 基于 SnmpSharpNet 开发
    C#实现ActiveMQ消息队列
    ActiveMQ 安装方法
    C# FluentFTP类上传下载文件
    .NET Core 之 Nancy 基本使用
  • 原文地址:https://www.cnblogs.com/skip1978/p/11169097.html
Copyright © 2011-2022 走看看