Advertisement
Guest User

Untitled

a guest
Nov 20th, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.15 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <list>
  4. #include <assert.h>
  5. #include <fstream>
  6.  
  7. struct MemoryBlock {
  8.     size_t start_index;
  9.     size_t size;
  10.     size_t heap_index;
  11.     bool is_free;
  12. };
  13.  
  14. struct HeapElement {
  15.     std::list<MemoryBlock>::iterator iter;
  16. };
  17.  
  18. class Heap {
  19. public:
  20.     HeapElement PopTop() {
  21.         HeapElement result = storage_[0];
  22.         Swap(0, storage_.size() - 1);
  23.         storage_.pop_back();
  24.         SinkDown(0);
  25.         return result;
  26.     }
  27.  
  28.     std::list<MemoryBlock>::iterator PeekTop() {
  29.         return storage_[0].iter;
  30.     }
  31.  
  32.     void Delete(size_t i_) {
  33.         Swap(i_, storage_.size() - 1);
  34.         storage_.pop_back();
  35.         SinkDown(i_);
  36.     }
  37.  
  38.     size_t Size() {
  39.         return storage_.size();
  40.     }
  41.  
  42.     void Insert(HeapElement new_element) {
  43.         storage_.push_back(new_element);
  44.         storage_[storage_.size() - 1].iter->heap_index = storage_.size() - 1;
  45.         BubbleUp(storage_.size() - 1);
  46.     }
  47.  
  48.     void BubbleUp(size_t i_) {
  49.         while (i_ > 0) {
  50.             size_t parent_idx = (i_ - 1) / 2;
  51.             if (CmpLt(parent_idx, i_)) {
  52.                 Swap(parent_idx, i_);
  53.                 i_ = parent_idx;
  54.             } else {
  55.                 break;
  56.             }
  57.         }
  58.     }
  59.  
  60.     void SinkDown(size_t i_) {
  61.         size_t length = storage_.size();
  62.  
  63.         while (i_ < length) {
  64.             size_t left_child_idx = 2 * i_ + 1;
  65.             size_t right_child_idx = 2 * i_ + 2;
  66.  
  67.             size_t min_index = i_;
  68.             if (left_child_idx < length && CmpLt(i_, left_child_idx)) {
  69.                 min_index = left_child_idx;
  70.             }
  71.  
  72.             if (right_child_idx < length && CmpLt(i_, right_child_idx)) {
  73.                 min_index = right_child_idx;
  74.             }
  75.  
  76.             if (i_ != min_index) {
  77.                 Swap(i_, min_index);
  78.                 i_ = min_index;
  79.             } else {
  80.                 break;
  81.             }
  82.         }
  83.     }
  84.  
  85. private:
  86.     bool CmpLt(size_t i_, size_t j_) {
  87.         if (storage_[i_].iter->size == storage_[j_].iter->size) {
  88.             return storage_[i_].iter->start_index > storage_[j_].iter->start_index;
  89.         } else {
  90.             return storage_[i_].iter->size < storage_[j_].iter->size;
  91.         }
  92.     }
  93.  
  94.     void Swap(size_t i_, size_t j_) {
  95.         HeapElement swap_elem = storage_[i_];
  96.         storage_[i_] = storage_[j_];
  97.         storage_[j_] = swap_elem;
  98.  
  99.         storage_[i_].iter->heap_index = i_;
  100.         storage_[j_].iter->heap_index = j_;
  101.     }
  102.  
  103.     std::vector<HeapElement> storage_;
  104. };
  105.  
  106. struct AllocationEvent {
  107.     bool success;
  108.     std::list<MemoryBlock>::iterator memory_block_iter;
  109. };
  110.  
  111. class MemoryManager {
  112. public:
  113.     explicit MemoryManager(size_t memory_size) {
  114.         MemoryBlock new_block;
  115.         new_block.start_index = 1;
  116.         new_block.size = memory_size;
  117.         new_block.is_free = true;
  118.  
  119.         blocks_list_.push_front(new_block);
  120.         std::list<MemoryBlock>::iterator iter = blocks_list_.begin();
  121.  
  122.         HeapElement new_elem;
  123.         new_elem.iter = iter;
  124.         free_heap_.Insert(new_elem);
  125.         // Push into memory_heap
  126.     }
  127.  
  128.     bool Allocate(size_t size_needed) {
  129.         auto max_block = free_heap_.PeekTop();
  130.         if (max_block->size < size_needed) {
  131.             AllocationEvent event;
  132.             event.success = false;
  133.             allocation_history_.push_back(event);
  134.  
  135.             std::cout << -1 << "\n";
  136.  
  137.             return false;
  138.         } else {
  139.             auto new_occupied_block = SplitOccupy(max_block, size_needed);
  140.             AllocationEvent event;
  141.             event.success = true;
  142.             event.memory_block_iter = new_occupied_block;
  143.             allocation_history_.push_back(event);
  144.  
  145.             std::cout << new_occupied_block->start_index << "\n";
  146.  
  147.             return true;
  148.         }
  149.     }
  150.  
  151.     void Free(size_t when_occupied) {
  152.         when_occupied--;
  153.  
  154.         if (allocation_history_[when_occupied].success) {
  155.             allocation_history_[when_occupied].success = false;
  156.  
  157.             auto occupied_iter = allocation_history_[when_occupied].memory_block_iter;
  158.  
  159.             if (occupied_iter == blocks_list_.begin()) {
  160.                 auto next_block = occupied_iter;
  161.                 next_block++;
  162.  
  163.                 if (next_block == blocks_list_.end()) {
  164.                     FreeIsolated(occupied_iter);
  165.                 } else {
  166.                     if (!next_block->is_free) {
  167.                         FreeIsolated(occupied_iter);
  168.                     } else {
  169.                         FreeBefore(occupied_iter, next_block);
  170.                     }
  171.                 }
  172.             } else {
  173.                 auto previous_block = occupied_iter;
  174.                 previous_block--;
  175.  
  176.                 auto next_block = occupied_iter;
  177.                 next_block++;
  178.  
  179.                 if (next_block == blocks_list_.end()) {
  180.                     if (!previous_block->is_free) {
  181.                         FreeIsolated(occupied_iter);
  182.                     } else {
  183.                         FreeAfter(previous_block, occupied_iter);
  184.                     }
  185.                 } else {
  186.                     if (!previous_block->is_free && !next_block->is_free) {
  187.                         FreeIsolated(occupied_iter);
  188.                     } else if (!previous_block->is_free && next_block->is_free) {
  189.                         FreeBefore(occupied_iter, next_block);
  190.                     } else if (previous_block->is_free && !next_block->is_free) {
  191.                         FreeAfter(previous_block, occupied_iter);
  192.                     } else if (previous_block->is_free && next_block->is_free) {
  193.                         previous_block->size += occupied_iter->size + next_block->size;
  194.                         free_heap_.Delete(next_block->heap_index);
  195.                         blocks_list_.erase(next_block);
  196.                         blocks_list_.erase(occupied_iter);
  197.                         free_heap_.BubbleUp(previous_block->heap_index);
  198.                     }
  199.                 }
  200.             }
  201.         }
  202.     }
  203.  
  204. private:
  205.     void FreeIsolated(std::list<MemoryBlock>::iterator occupied_iter) {
  206.         occupied_iter->is_free = true;
  207.         HeapElement new_elem;
  208.         new_elem.iter = occupied_iter;
  209.         free_heap_.Insert(new_elem);
  210.     }
  211.  
  212.     void FreeBefore(std::list<MemoryBlock>::iterator occupied_iter,
  213.                     std::list<MemoryBlock>::iterator next_block) {
  214.         occupied_iter->is_free = true;
  215.         next_block->size += occupied_iter->size;
  216.         next_block->start_index = occupied_iter->start_index;
  217.         free_heap_.BubbleUp(next_block->heap_index);
  218.         blocks_list_.erase(occupied_iter);
  219.     }
  220.  
  221.     void FreeAfter(std::list<MemoryBlock>::iterator previous_block,
  222.                    std::list<MemoryBlock>::iterator occupied_iter) {
  223.         previous_block->size += occupied_iter->size;
  224.         free_heap_.BubbleUp(previous_block->heap_index);
  225.         blocks_list_.erase(occupied_iter);
  226.     }
  227.  
  228.     std::list<MemoryBlock>::iterator SplitOccupy(std::list<MemoryBlock>::iterator iter,
  229.                                                  size_t size_needed) {
  230.         assert(iter->size >= size_needed);
  231.         assert(iter->is_free);
  232.  
  233.         if (iter->size > size_needed) {
  234.             MemoryBlock new_occupied_block;
  235.             new_occupied_block.is_free = false;
  236.             new_occupied_block.start_index = iter->start_index;
  237.             new_occupied_block.size = size_needed;
  238.  
  239.             iter->size -= size_needed;
  240.             iter->start_index = new_occupied_block.start_index + size_needed;
  241.             free_heap_.SinkDown(iter->heap_index);
  242.  
  243.             auto new_occupied_iter = blocks_list_.insert(iter, new_occupied_block);
  244.  
  245.             return new_occupied_iter;
  246.         } else {
  247.             iter->is_free = false;
  248.             free_heap_.Delete(iter->heap_index);
  249.  
  250.             return iter;
  251.         }
  252.     }
  253.     std::list<MemoryBlock> blocks_list_;
  254.     Heap free_heap_;
  255.     std::vector<AllocationEvent> allocation_history_;
  256. };
  257.  
  258. struct Query {
  259.     bool is_alloc;
  260.     size_t value;
  261.     Query(bool is_alloc_, size_t value_)
  262.             : is_alloc(is_alloc_), value(value_) {}
  263. };
  264.  
  265. void ReadInput(const std::string& filename,
  266.                size_t* memory_size, std::vector<int64_t>* queries) {
  267.     std::ifstream in_stream;
  268.     in_stream.open(filename);
  269.  
  270.     if (!in_stream.is_open()) {
  271.         std::cerr << "File not found:" << filename;
  272.         exit(1);
  273.     }
  274.  
  275.     size_t num_queries;
  276.     in_stream >> *memory_size >> num_queries;
  277.     // std::cout << *memory_size  << " " << num_queries << std::endl;
  278.     queries->resize(num_queries);
  279.     for (auto& query : *queries) {
  280.         in_stream >> query;
  281.     }
  282. }
  283.  
  284. int main() {
  285.     std::string filename = "input.txt";
  286.  
  287.     size_t memory_size;
  288.     std::vector<int64_t> queries;
  289.  
  290.     ReadInput(filename, &memory_size, &queries);
  291.  
  292.     MemoryManager mgr(memory_size);
  293.  
  294.     for (const auto& query : queries) {
  295.         // std::cout << query << std::endl;
  296.         if (query > 0) {
  297.             mgr.Allocate(static_cast<size_t>(query));
  298.         } else {
  299.             mgr.Free(static_cast<size_t>(-query));
  300.         }
  301.     }
  302.  
  303.     return 0;
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement