vadimk772336

принята (дерево отрезков)

Dec 9th, 2021
949
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.17 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4.  
  5. const int MAX = 2e5;
  6.  
  7. struct vertex
  8. {
  9.     int res;
  10.     int left;
  11.     int right;
  12. };
  13.  
  14. class Segment_Tree
  15. {
  16.     struct vertex* tree;
  17.     int tree_size;
  18.     int count_numbers;
  19.     std::vector<int> numbers;
  20.  
  21. public:
  22.     void build_tree(int v, int tl, int tr);
  23.     int to_deg_of_two(std::vector<int>& numbers, int count_numbers);
  24.     void Initialize(int count_numbers);
  25.     void set_number(int k, int x);
  26.     int get_min(int node, int a, int b);
  27.     int find_spot(int start_number);
  28.     int free_up(int number);
  29.     void print_tree();
  30.     void permute_request(char s, std::string number);
  31. };
  32.  
  33. void Segment_Tree::build_tree(int v, int tl, int tr)
  34. {
  35.  
  36.  
  37.     if (tr - tl == 1)
  38.     {
  39.         this->tree[v].res = this->numbers[tl];
  40.         this->tree[v].left = tl;
  41.         this->tree[v].right = tr;
  42.     }
  43.     else
  44.     {
  45.         int tm = (tl + tr) / 2;
  46.         build_tree(v * 2 + 1, tl, tm);
  47.         build_tree(v * 2 + 2, tm, tr);
  48.         this->tree[v].left = tl;
  49.         this->tree[v].right = tr;
  50.  
  51.         if (tree[v * 2 + 1].res < tree[v * 2 + 2].res)
  52.             this->tree[v].res = tree[v * 2 + 1].res;
  53.         else
  54.             this->tree[v].res = tree[v * 2 + 2].res;
  55.     }
  56. }
  57.  
  58. int Segment_Tree::to_deg_of_two(std::vector<int>& numbers, int count_numbers)
  59. {
  60.  
  61.     int p = 1;
  62.     while (count_numbers > p)
  63.         p *= 2;
  64.  
  65.     for (int i = 0; i < p - count_numbers; ++i)
  66.         this->numbers.push_back(MAX);
  67.  
  68.     return p;
  69. }
  70.  
  71. void Segment_Tree::Initialize(int count_numbers)
  72. {
  73.  
  74.  
  75.     this->count_numbers = count_numbers;
  76.     this->numbers.clear();
  77.     this->numbers.resize(count_numbers);
  78.  
  79.     for (int i = 1; i <= count_numbers; ++i)
  80.         this->numbers[i - 1] = i;
  81.  
  82.     this->count_numbers = to_deg_of_two(numbers, count_numbers);
  83.     this->tree_size = 2 * this->count_numbers - 1;
  84.     this->tree = new vertex[tree_size];
  85.  
  86.     build_tree(0, 0, this->count_numbers);
  87. }
  88.  
  89.  
  90. void Segment_Tree::set_number(int k, int x)
  91. {
  92.     int v = this->count_numbers - 1 + k;
  93.     this->tree[v].res = x;
  94.     while (v > 0)
  95.     {
  96.         v = (v - 1) / 2;
  97.  
  98.         int l_min = tree[2 * v + 1].res;
  99.         int r_min = tree[2 * v + 2].res;
  100.         (l_min < r_min) ? this->tree[v].res = l_min : this->tree[v].res = r_min;
  101.     }
  102. }
  103.  
  104. int Segment_Tree::get_min(int node, int a, int b)
  105. {
  106.     int l = tree[node].left;
  107.     int r = tree[node].right;
  108.     if (r <= a || l >= b)
  109.         return MAX;
  110.  
  111.     if (r <= b & l >= a)
  112.         return tree[node].res;
  113.  
  114.     int m_one = get_min(node * 2 + 1, a, b);
  115.     int m_two = get_min(node * 2 + 2, a, b);
  116.     return (m_one < m_two) ? m_one : m_two;
  117. }
  118.  
  119. int Segment_Tree::find_spot(int start_number)
  120. {
  121.  
  122.     int pos = (start_number - 1) + (this->tree_size - this->count_numbers);
  123.  
  124.     if (tree[pos].res != MAX)
  125.     {
  126.  
  127.         set_number(start_number - 1, MAX);
  128.         return start_number;
  129.     }
  130.  
  131.     else
  132.     {
  133.         int min_num = get_min(0, start_number - 1, this->count_numbers);
  134.  
  135.         if (min_num == MAX)
  136.         {
  137.             min_num = get_min(0, 0, start_number);
  138.  
  139.             if (min_num == MAX)
  140.                 return -1;
  141.             else
  142.             {
  143.                 set_number(min_num - 1, MAX);
  144.                 return min_num;
  145.             }
  146.         }
  147.  
  148.         else
  149.         {
  150.             set_number(min_num - 1, MAX);
  151.             return min_num;
  152.         }
  153.     }
  154. }
  155.  
  156. int Segment_Tree::free_up(int number)
  157. {
  158.     int pos = (number - 1) + (this->tree_size - this->count_numbers);
  159.  
  160.     if (tree[pos].res == MAX)
  161.     {
  162.         set_number(number - 1, number);
  163.         return 0;
  164.     }
  165.     else
  166.         return -2;
  167. }
  168.  
  169. void Segment_Tree::permute_request(char s, std::string number)
  170. {
  171.     int num = std::stoi(number);
  172.     if (s == '+')
  173.         std::cout << find_spot(num) << std::endl;
  174.     else
  175.         std::cout << free_up(num) << std::endl;
  176. }
  177.  
  178. int main()
  179. {
  180.  
  181.     int n, m;
  182.     char s;
  183.     std::string number;
  184.     std::cin >> n >> m;
  185.  
  186.     Segment_Tree tree;
  187.     tree.Initialize(n);
  188.  
  189.     for (int i = 0; i < m; ++i)
  190.     {
  191.         std::cin >> s >> number;
  192.         tree.permute_request(s, number);
  193.     }
  194.  
  195.     return 0;
  196. }
  197.  
Advertisement
Add Comment
Please, Sign In to add comment