Mephistopheles_

Splay tree

Nov 13th, 2021
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.75 KB | None | 0 0
  1. #pragma GCC optimize ("Ofast,unroll-loops")
  2. #pragma GCC target ("avx2,fma")
  3. #include<bits/stdc++.h>
  4.  
  5. #include <utility>
  6. using namespace std;
  7.  
  8.  
  9. //rope
  10. #define forx(i,a,b) for (int i = a; i < b; i++)
  11. #define INF int(1e9)
  12. #define all(x2) begin(x2),end(x2)
  13. #define isz(t) ((ll)(t.size()))
  14. #define last(x) (*(x.end()-1))
  15. #define mod ll(1e9+7)
  16. #define ft first
  17. #define sd second
  18. #define pr pair
  19. #define sh(x) false //cerr<<#x<<" = "<<x<<'\n'
  20. //#define debug
  21.  
  22. using ll= long long;//
  23. using ld= long double;
  24. using ull=unsigned long long;
  25. using ii = pair<ll, ll>;
  26. string to_string(string s){
  27.     return s;
  28. }
  29. template<typename T>
  30. ostream& print_range(ostream& os,T begin,T end){
  31.     for(auto it=begin;it!=end;++it)
  32.         os<<*it<<' ';
  33.     os<<'\n';
  34.     return os;
  35. }
  36. template<typename ...T>
  37. ostream& operator<<(ostream& os,const vector<T...>&v){
  38.     return print_range(os,v.begin(),v.end());
  39. }
  40. template<typename ...Args>
  41. void printer(Args&&... args) {
  42.     (std::cerr << ... <<( to_string(args)+" ")) << '\n';
  43. }
  44.  
  45. template<typename T, typename... Args>
  46. void push_back_vec(std::vector<T>& v, Args&&... args)
  47. {
  48.     (v.push_back(std::forward<Args>(args)), ...);
  49. }
  50. template<class ...Args>
  51. void input(Args&... args) {
  52.     (cin>>...>>args);
  53. }
  54. template<typename T>
  55. T minimum(T x) {
  56.     return x;
  57. }
  58.  
  59. template<typename T, typename... Pack>
  60. auto minimum(T x, Pack... p) {
  61.     using common = typename std::common_type<T, Pack...>::type;
  62.     return std::min((common)x, (common)minimum(p...));
  63. }
  64.  
  65. template<typename T>
  66. T maximum(T x) {
  67.     return x;
  68. }
  69.  
  70. template<typename T, typename... Pack>
  71. auto maximum(T x, Pack... p) {
  72.     using common = typename std::common_type<T, Pack...>::type;
  73.     return std::max((common)x, (common)maximum(p...));
  74. }
  75. class splay_tree{
  76.     class node{
  77.     public:
  78.         int key;
  79.         node *left, *right;
  80.         node(int key) : key(key),left(nullptr),right(nullptr){}
  81.     };
  82.     node *tree_root;
  83.  
  84.     // Эта функция поднимет ключ
  85.     // в корень, если он присутствует в дереве.
  86.     // Если такой ключ отсутствует в дереве, она
  87.     // поднимет в корень самый последний элемент,
  88.     // к которому был осуществлен доступ.
  89.     // Эта функция изменяет дерево
  90.     // и возвращает новый корень (root).
  91.     node *rightRotate(node *x)
  92.     {
  93.         node *y = x->left;
  94.         x->left = y->right;
  95.         y->right = x;
  96.         return y;
  97.     }
  98.  
  99.     // Служебная функция для разворота поддерева с корнем x влево
  100.     // Смотрите диаграмму, приведенную выше.
  101.     node *leftRotate(node *x)
  102.     {
  103.         node *y = x->right;
  104.         x->right = y->left;
  105.         y->left = x;
  106.         return y;
  107.     }
  108.     // Эта функция поднимет ключ
  109.     // в корень, если он присутствует в дереве.
  110.     // Если такой ключ отсутствует в дереве, она
  111.     // поднимет в корень самый последний элемент,
  112.     // к которому был осуществлен доступ.
  113.     // Эта функция изменяет дерево
  114.     // и возвращает новый корень (root).
  115.     node *splay(node *root, int key)
  116.     {
  117.         // Базовые случаи: root равен NULL или
  118.         // ключ находится в корне
  119.         if (root == nullptr || root->key == key)
  120.             return root;
  121.  
  122.         // Ключ лежит в левом поддереве
  123.         if (root->key > key)
  124.         {
  125.             // Ключа нет в дереве, мы закончили
  126.             if (root->left == nullptr) return root;
  127.  
  128.             // Zig-Zig (Левый-левый)
  129.             if (root->left->key > key)
  130.             {
  131.                 // Сначала рекурсивно поднимем
  132.                 // ключ как корень left-left
  133.                 root->left->left = splay(root->left->left, key);
  134.  
  135.                 // Первый разворот для root,
  136.                 // второй разворот выполняется после else
  137.                 root = rightRotate(root);
  138.             }
  139.             else if (root->left->key < key) // Zig-Zag (Левый-правый)
  140.                 {
  141.                 // Сначала рекурсивно поднимаем
  142.                 // ключ как корень left-right
  143.                 root->left->right = splay(root->left->right, key);
  144.  
  145.                 // Выполняем первый разворот для root->left
  146.                 if (root->left->right != nullptr)
  147.                     root->left = leftRotate(root->left);
  148.                 }
  149.  
  150.             // Выполняем второй разворот для корня
  151.             return (root->left == nullptr)? root: rightRotate(root);
  152.         }
  153.         else // Ключ находится в правом поддереве
  154.         {
  155.             // Ключа нет в дереве, мы закончили
  156.             if (root->right == nullptr) return root;
  157.  
  158.             // Zag-Zig (Правый-левый)
  159.             if (root->right->key > key)
  160.             {
  161.                 // Поднять ключ как корень right-left
  162.                 root->right->left = splay(root->right->left, key);
  163.  
  164.                 // Выполняем первый поворот для root->right
  165.                 if (root->right->left != nullptr)
  166.                     root->right = rightRotate(root->right);
  167.             }
  168.             else if (root->right->key < key)// Zag-Zag (Правый-правый)
  169.                 {
  170.                 // Поднимаем ключ как корень
  171.                 // right-right и выполняем первый разворот
  172.                 root->right->right = splay(root->right->right, key);
  173.                 root = leftRotate(root);
  174.                 }
  175.  
  176.             // Выполняем второй разворот для root
  177.             return (root->right == nullptr)? root: leftRotate(root);
  178.         }
  179.     }
  180.     // Служебная функция для вывода
  181.     // обхода в дерева ширину.
  182.     // Функция также выводит высоту каждого узла
  183.     void preOrder(node *root)
  184.     {
  185.         if (root != nullptr)
  186.         {
  187.             preOrder(root->left);
  188.             cout<<root->key<<" ";
  189.             preOrder(root->right);
  190.         }
  191.     }
  192.     pair<node*,node*> split(node* root,int key){
  193.         if(root==nullptr){
  194.             return{nullptr,nullptr};
  195.         }
  196.         root=splay(root,key);
  197.         if(root->key<key){
  198.             auto right=root->right;
  199.             root->right=nullptr;
  200.             return {root,right};
  201.         }
  202.         else{
  203.             auto left=root->left;
  204.             root->left=nullptr;
  205.             return {left,root};
  206.         }
  207.     }
  208.     node* merge(node* left,node* right){
  209.         if(left==nullptr)
  210.             return right;
  211.         if(nullptr==right)
  212.             return left;
  213.         node* root=left;
  214.         while(root->right!=nullptr)
  215.             root=root->right;
  216.         root=splay(left,root->key);
  217.         root->right=right;
  218.         return root;
  219.     }
  220.     public:
  221.     splay_tree():tree_root(nullptr){}
  222.     void insert(int key){
  223.         auto[left,right]=split(tree_root,key);
  224.         tree_root=new node(key);
  225.         tree_root->left=left;
  226.         tree_root->right=right;
  227.     }
  228.     void erase(int key){
  229.         auto root=splay(tree_root,key);
  230.         tree_root= merge(root->left,root->right);
  231.     }
  232.     void couter(){
  233.         preOrder(tree_root);
  234.         cout<<'\n';
  235.     }
  236.     bool contains(int key){
  237.         tree_root=splay(tree_root,key);
  238.         return nullptr!=tree_root && tree_root->key==key;
  239.     }
  240. };
  241.  
  242. int  main() {
  243. //    d[i][j]=d[i+1][j-1] +2* s[i]==s[j]
  244. //    d[i][j]=наибольшая подпоследовательность-палиндром на отрезке  i j
  245. //    if s[i]==s[j] then remax(d[i][j],d[i+1][j-1] +2)
  246. //    remax(d[i][j], d[i + 1][j])
  247. //    remax(d[i][j], d[i][j - 1])
  248. //    ios::sync_with_stdio(false);
  249. //    cin.tie(nullptr);
  250. //    cout.tie(nullptr);
  251. //    cout.setf(ios::fixed);
  252. //    cout.precision(15);
  253. //    solution();
  254.     splay_tree tr;
  255.     for(int i: vector<int>{100,50,200,40,30,20}){
  256.         tr.insert(i);
  257.     }
  258.     tr.couter();
  259.     cout<<tr.contains(50)<<'\n';
  260.     tr.erase(50);
  261.     cout<<tr.contains(50)<<'\n';
  262.     tr.couter();
  263.     cout<<tr.contains(150)<<'\n';
  264.     tr.insert(150);
  265.     cout<<tr.contains(150)<<'\n';
  266.     tr.couter();
  267. }
  268.  
  269.  
Advertisement
Add Comment
Please, Sign In to add comment