Al3XS0n

AVL-tree + K-order statistic

Nov 24th, 2019
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.46 KB | None | 0 0
  1. /*
  2.  * Дано число N и N строк.
  3.  * Каждая строка содержащит команду добавления или удаления натуральных чисел, а также запрос на получение k-ой порядковой
  4.  * статистики. Команда добавления числа A задается положительным числом A, команда удаления числа A задается отрицательным
  5.  * числом “-A”. Запрос на получение k-ой порядковой статистики задается числом k. Требуемая скорость выполнения запроса -
  6.  * O(log n).
  7. */
  8. #include <iostream>
  9. #include <vector>
  10.  
  11. using namespace std;
  12.  
  13. struct Node {
  14.     int key = 0;
  15.     int height = 0;
  16.     int size = 0;
  17.     Node* left = nullptr;
  18.     Node* right = nullptr;
  19.  
  20.     Node() = default;
  21.  
  22.     Node(int _key, int _height, int _size) : key(_key), height(_height), size(_size) {}
  23.  
  24.     ~Node() {
  25.         delete left;
  26.         delete right;
  27.     }
  28. };
  29.  
  30. class AVL {
  31. public:
  32.     AVL() = default;
  33.  
  34.     ~AVL();
  35.  
  36.     bool IsEmpty() { return root == nullptr; }
  37.  
  38.     Node* Insert(Node* node, int key);
  39.  
  40.     void Insert(int key) { root = Insert(root, key); }
  41.  
  42.     Node* Remove(Node* node, int key);
  43.  
  44.     void Remove(int key) { root = Remove(root, key); }
  45.  
  46.     int FindStat(int k) { return FindStat(root, k); }
  47.  
  48. private:
  49.     Node* root = nullptr;
  50.  
  51.     Node* FindMin(Node* node) const { return node->left != nullptr ? FindMin(node->left) : node; }
  52.  
  53.     Node* RemoveMin(Node* node);
  54.  
  55.     int GetHeight(Node* node) const;
  56.  
  57.     int GetSize(Node* node) const;
  58.  
  59.     int BalanceDif(Node* node) const;
  60.  
  61.     void UpdSize(Node* node);
  62.  
  63.     void UpdHeight(Node* node);
  64.  
  65.     Node* RotateLeft(Node* node);
  66.  
  67.     Node* RotateRight(Node* node);
  68.  
  69.     Node* Balance(Node* node);
  70.  
  71.     int FindStat(Node* node, int k);
  72. };
  73.  
  74. AVL::~AVL() {
  75.     delete root;
  76. }
  77.  
  78. int AVL::GetHeight(Node* node) const {
  79.     if (node == nullptr) {
  80.         return 0;
  81.     }
  82.     return node->height;
  83. }
  84.  
  85. int AVL::GetSize(Node* node) const {
  86.     if (node == nullptr) {
  87.         return 0;
  88.     }
  89.     return node->size;
  90. }
  91.  
  92. int AVL::BalanceDif(Node* node) const {
  93.     if (node == nullptr) {
  94.         return 0;
  95.     }
  96.     return GetHeight(node->right) - GetHeight(node->left);
  97. }
  98.  
  99. void AVL::UpdHeight(Node* node) {
  100.     if (node == nullptr) {
  101.         return;
  102.     }
  103.     int heightLeft = GetHeight(node->left);
  104.     int heightRight = GetHeight(node->right);
  105.     node->height = max(heightLeft, heightRight) + 1;
  106. }
  107.  
  108. void AVL::UpdSize(Node* node) {
  109.     if (node == nullptr) {
  110.         return;
  111.     }
  112.     int sizeLeft = GetSize(node->left);
  113.     int sizeRight = GetSize(node->right);
  114.     node->size = sizeLeft + sizeRight + 1;
  115. }
  116.  
  117. Node* AVL::RotateLeft(Node* node) {
  118.     Node*_node = node->right;
  119.     node->right = _node->left;
  120.     _node->left = node;
  121.  
  122.     UpdHeight(node);
  123.     UpdHeight(_node);
  124.     UpdSize(node);
  125.     UpdSize(_node);
  126.  
  127.     return _node;
  128. }
  129.  
  130. Node* AVL::RotateRight(Node* node) {
  131.     Node* _node = node->left;
  132.     node->left = _node->right;
  133.     _node->right = node;
  134.  
  135.     UpdHeight(node);
  136.     UpdHeight(_node);
  137.     UpdSize(node);
  138.     UpdSize(_node);
  139.  
  140.     return _node;
  141. }
  142.  
  143. Node* AVL::Balance(Node* node) {
  144.     UpdHeight(node);
  145.     UpdSize(node);
  146.  
  147.     if (BalanceDif(node) == 2) {
  148.         if (BalanceDif(node->right) < 0) {
  149.             node->right = RotateRight(node->right);
  150.         }
  151.         return RotateLeft(node);
  152.     } else if (BalanceDif(node) == -2) {
  153.         if (BalanceDif(node->left) > 0){
  154.             node->left = RotateLeft(node->left);
  155.         }
  156.         return RotateRight(node);
  157.     }
  158.     return node;
  159. }
  160.  
  161. Node* AVL::RemoveMin(Node* node) {
  162.     if (node->left == nullptr) {
  163.         return node->right;
  164.     }
  165.     node->left = RemoveMin(node->left);
  166.     return Balance(node);
  167. }
  168.  
  169. Node* AVL::Insert(Node* node, int key) {
  170.     if (node == nullptr) {
  171.         return new Node(key, 1, 1);
  172.     } else if (key < node->key) {
  173.         node->left = Insert(node->left, key);
  174.     } else {
  175.         node->right = Insert(node->right, key);
  176.     }
  177.     return Balance(node);
  178. }
  179.  
  180. Node* AVL::Remove(Node* node, int key) {
  181.     if (node == nullptr) {
  182.         return nullptr;
  183.     }
  184.     if (key < node->key) {
  185.         node->left = Remove(node->left, key);
  186.     } else if (key > node->key) {
  187.         node->right = Remove(node->right, key);
  188.     } else {
  189.         if (node->right == nullptr) {
  190.             return node->left;
  191.         }
  192.         if (node->left == nullptr) {
  193.             return node->right;
  194.         }
  195.         Node* _node = node;
  196.         node = FindMin(_node->right);
  197.         node->right = RemoveMin(_node->right);
  198.         node->left = _node->left;
  199.         return Balance(node);
  200.     }
  201.     return Balance(node);
  202. }
  203.  
  204. int AVL::FindStat(Node* node, int k) {
  205.     if (GetSize(node->left) + 1 == k) {
  206.         return node->key;
  207.     } else if (GetSize(node->left) >= k) {
  208.         return FindStat(node->left, k);
  209.     } else {
  210.         return FindStat(node->right, k - (GetSize(node->left) + 1));
  211.     }
  212. }
  213.  
  214. int main() {
  215.     int n;
  216.     AVL tree;
  217.     cin >> n;
  218.     for (int i = 0; i < n; ++i) {
  219.         int a, k;
  220.         cin >> a >> k;
  221.         if (a > 0) {
  222.             tree.Insert(a);
  223.         } else {
  224.             tree.Remove(abs(a));
  225.         }
  226.         cout << tree.FindStat(k + 1) << endl;
  227.     }
  228.     return 0;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment