vadimk772336

очищен

Dec 9th, 2021
848
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.46 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. using namespace std;
  5.  
  6. const int MAX = 2e5;
  7.  
  8. struct vertex
  9. {
  10.     int res;
  11.     int left;
  12.     int right;
  13. };
  14.  
  15. class Segment_Tree
  16. {
  17.     struct vertex* tree;
  18.     int tree_size;
  19.     int count_numbers;
  20.     std::vector<int> numbers;
  21.  
  22. public:
  23.     void build_tree(int v, int tl, int tr);
  24.     int to_deg_of_two(std::vector<int>& numbers, int count_numbers);
  25.     void Initialize(int count_numbers);
  26.     void set(int k, int x);
  27.     int get_min(int node, int a, int b);
  28.     int find_spot(int start_number);
  29.     int free_up(int number);
  30.     void print_tree();
  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(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 m1 = get_min(node * 2 + 1, a, b);
  115.     int m2 = get_min(node * 2 + 2, a, b);
  116.     return (m1 < m2) ? m1 : m2;
  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(start_number - 1, MAX);
  128.         return start_number;
  129.     }
  130.  
  131.     else
  132.     {
  133.         print_tree();
  134.         int min_num = get_min(0, start_number - 1, this->count_numbers + 1);
  135.  
  136.         if (min_num == MAX)
  137.         {
  138.             min_num = get_min(0, 0, start_number);
  139.  
  140.             if (min_num == MAX)
  141.                 return -1;
  142.             else
  143.             {
  144.                 set(min_num - 1, MAX);
  145.                 return min_num;
  146.             }
  147.         }
  148.  
  149.         else
  150.         {
  151.             set(min_num - 1, MAX);
  152.             return min_num;
  153.         }
  154.     }
  155. }
  156.  
  157. int Segment_Tree::free_up(int number)
  158. {
  159.     int pos = (number - 1) + (this->tree_size - this->count_numbers);
  160.  
  161.     if (tree[pos].res == MAX)
  162.     {
  163.         set(number - 1, number);
  164.         return 0;
  165.     }
  166.     else
  167.         return -2;
  168. }
  169.  
  170. void Segment_Tree::print_tree()
  171. {
  172.     int k = 2;
  173.     cout << "\ni= " << 0 << " (" << tree[0].left << ";" << tree[0].right << "): " << tree[0].res
  174.          << endl;
  175.     for (int i = 1; i < this->tree_size; ++i)
  176.     {
  177.         if (i == 2 * k - 1)
  178.         {
  179.             k *= 2;
  180.             cout << endl;
  181.         }
  182.         cout << "i= " << i << " (" << tree[i].left << ";" << tree[i].right << "): " << tree[i].res
  183.              << "; ";
  184.     }
  185.     cout << endl;
  186. }
  187.  
  188. int main()
  189. {
  190.  
  191.     int n, m;
  192.     char s;
  193.     string number;
  194.     cin >> n >> m;
  195.  
  196.     Segment_Tree tree;
  197.     tree.Initialize(n);
  198.  
  199.  
  200.     for (int i = 0; i < m; ++i)
  201.     {
  202.  
  203.         cin >> s;
  204.         cin >> number;
  205.         int num = stoi(number);
  206.         if (s == '+')
  207.             cout << tree.find_spot(num) << endl;
  208.         else
  209.             cout << tree.free_up(num) << endl;
  210.     }
  211.  
  212.     return 0;
  213. }
  214.  
Advertisement
Add Comment
Please, Sign In to add comment