雾
/*
* 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;
}
}
}
}