Advertisement
TrickmanOff

sol informatics №934 25p.

Aug 11th, 2019
266
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.98 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <iostream>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <functional>
  7. #include <bitset>
  8. #include <string>
  9. #include <stack>
  10. #include <time.h>
  11. #include <random>
  12. #include <unordered_set>
  13. #include <queue>
  14. using namespace std;
  15.  
  16. #define ll long long
  17. #define cin in
  18. #define cout out
  19. #define pii pair<int, int>
  20. #define ld long double
  21. #define u_set unordered_set
  22. #define uid uniform_int_distribution
  23.  
  24. ifstream in("input.txt");
  25. ofstream out("output.txt");
  26.  
  27. int H, W, n, cur_h = 1, sz = 0;
  28. const int TREE_SZ = 524288, INF = 2e9;
  29. int tree[TREE_SZ];
  30.  
  31. struct line{
  32.     int len, h;
  33.     line() : len(W), h(cur_h++) {}
  34. };
  35.  
  36. //size of 'lines' = cur_h-1 in the beginning of each block
  37. vector<line> lines;
  38.  
  39. void upd(int v) {
  40.     int l = tree[2*v];
  41.     int r = tree[2*v+1];
  42.     if(r == INF || (l != INF && lines[l].h < lines[r].h))
  43.         tree[v] = l;
  44.     else
  45.         tree[v] = r;
  46. }
  47.  
  48. void build(int v, int lb, int rb) {
  49.     if(lb == rb) {
  50.         tree[v] = lb;
  51.         return;
  52.     }
  53.    
  54.     int mid = (lb + rb)/2;
  55.     build(2*v, lb, mid);
  56.     build(2*v+1, mid+1, rb);
  57.    
  58.     upd(v);
  59. }
  60.  
  61. void rebuild() {
  62.     fill(tree, tree+TREE_SZ, INF);
  63.     build(1, 0, sz-1);
  64. }
  65.  
  66. void del(int v, int lb, int rb, int pos) {
  67.     if(lb == rb && rb == pos) {
  68.         tree[v] = INF;
  69.         return;
  70.     }
  71.    
  72.     int mid = (lb + rb)/2;
  73.     if(pos <= mid)
  74.         del(2*v, lb, mid, pos);
  75.     else
  76.         del(2*v+1, mid+1, rb, pos);
  77.    
  78.     upd(v);
  79. }
  80.  
  81. void del(int pos) {
  82.     del(1, 0, sz-1, pos);
  83. }
  84.  
  85. int get_min(int v, int l, int r, int lb, int rb) {
  86.     if(l > rb || r < lb)
  87.         return INF;
  88.    
  89.     if(lb == l && rb == r)
  90.         return tree[v];
  91.    
  92.     int mid = (lb + rb)/2;
  93.    
  94.     int l_p = get_min(2*v, l, min(mid, r), lb, mid);
  95.     int r_p = get_min(2*v+1, max(mid+1, l), r, mid+1, rb);
  96.    
  97.     if(l_p == INF && r_p == INF)
  98.         return INF;
  99.    
  100.     if(r_p == INF || (l_p != INF && lines[l_p].h < lines[r_p].h))
  101.         return l_p;
  102.     else
  103.         return r_p;
  104. }
  105.  
  106. int get_min(int l, int r) {
  107.     return get_min(1, l, r, 0, sz-1);
  108. }
  109.  
  110. //finds first num that has more or equal 'len' than 'a' and returns its position in the array
  111. int bin_search(int a) {
  112.     if(lines.back().len < a)
  113.         return -1;
  114.    
  115.     int l = -1, r = sz - 1;
  116.    
  117.     while(r - l > 1) {
  118.         int mid = (l+r)/2;
  119.         if(lines[mid].len >= a)
  120.             r = mid;
  121.         else
  122.             l = mid;
  123.     }
  124.    
  125.     return r;
  126. }
  127.  
  128. class Compare{
  129. public:
  130.     bool operator()(const line &a, const line &b) const {
  131.         return a.len < b.len;
  132.     }
  133. };
  134.  
  135. void resort(vector<line> &taken) {
  136.     vector<line> new_array;
  137.    
  138.     for(line x: lines)
  139.         new_array.push_back(x);
  140.    
  141.     for(line x : taken)
  142.         new_array.push_back(x);
  143.    
  144.     lines = new_array;
  145.    
  146.     sort(lines.begin(), lines.end(), Compare());
  147.     sz = (int)lines.size();
  148. }
  149.  
  150. vector<int> queries;
  151.  
  152. void gen() {
  153.     int len = (int) sqrt(n) + 1;
  154.    
  155.     for(int bl = 0; bl <= len; bl++) {
  156.         vector<line> taken;
  157.        
  158.         for(int i = bl*len; i < min(n, (bl+1) * len); i++) {
  159.            
  160.             int cur_w = queries[i];
  161.            
  162.             int tree_min = INF;
  163.            
  164.            
  165.             if(sz > 0) {
  166.                 int p = bin_search(cur_w);
  167.                 if(p != -1)
  168.                     tree_min = get_min(p, sz-1);
  169.             }
  170.            
  171.             //минимальный подходящий из taken
  172.             int taken_pos = -1, taken_min = INF;
  173.             for(int j = 0; j < taken.size(); j++) {
  174.                 line x = taken[j];
  175.                
  176.                 if(x.len >= cur_w && x.h < taken_min) {
  177.                     taken_pos = j;
  178.                     taken_min = x.h;
  179.                 }
  180.             }
  181.            
  182.             int ans = -1;
  183.            
  184.             if(taken_min < tree_min) {
  185.                 taken[taken_pos].len -= cur_w;
  186.                 ans = taken[taken_pos].h;
  187.             }
  188.             else if(tree_min == INF) {
  189.                 if(cur_h > H || cur_w > W)
  190.                 //if(cur_h > H)
  191.                     ans = -1;
  192.                 else {
  193.                     ans = cur_h;
  194.                    
  195.                     taken.push_back(line());
  196.                     taken.back().len -= cur_w;
  197.                 }
  198.             }
  199.             else {
  200.                 ans = lines[tree_min].h;
  201.                 lines[tree_min].len -= cur_w;
  202.                 taken.push_back(lines[tree_min]);
  203.                
  204.                 del(tree_min);
  205.             }
  206.            
  207.             cout << ans << '\n';
  208.         }
  209.        
  210.         if(!taken.empty()) {
  211.             resort(taken);
  212.             rebuild();
  213.         }
  214.     }
  215. }
  216.  
  217. void input() {
  218.     cin >> H >> W >> n;
  219.     queries.resize(n);
  220.     for(int &x : queries)
  221.         cin >> x;
  222.    
  223.     for(int i = 0; i < TREE_SZ; i++)
  224.         tree[i] = INF;
  225. }
  226.  
  227. int main()
  228. {
  229.     input();
  230.     gen();
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement