Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.10 KB | None | 0 0
  1. #include <algorithm>
  2. #include <functional>
  3. #include <iostream>
  4. #include <list>
  5. #include <memory>
  6. #include <stdexcept>
  7. #include <vector>
  8. #include <utility>
  9.  
  10. template <class T, class Compare = std::less<T>>
  11. class Heap {
  12. public:
  13.   using IndexChangeObserver =
  14.     std::function<void(const T& element, size_t new_element_index)>;
  15.  
  16.   static constexpr size_t k_null_index = static_cast<size_t>(-1);
  17.  
  18.   explicit Heap(
  19.     Compare compare = Compare(),
  20.     IndexChangeObserver index_change_observer = IndexChangeObserver()) {
  21.     compare_ = compare;
  22.     index_change_observer_ = index_change_observer;
  23.   }
  24.  
  25.   size_t push(const T& value) {
  26.     elements_.push_back(value);
  27.     NotifyIndexChange(value, size() - 1);
  28.     return SiftUp(elements_.size() - 1);
  29.   }
  30.   void erase(size_t index) {
  31.     elements_[index] = elements_[0];
  32.     NotifyIndexChange(elements_[index], index);
  33.     SiftUp(index);
  34.     pop();
  35.   }
  36.   const T& top() const {
  37.     return elements_[0];
  38.   }
  39.   void pop() {
  40.     NotifyIndexChange(elements_[0], k_null_index);
  41.     if (size() > 1) {
  42.       elements_[0] = elements_[size() - 1];
  43.       NotifyIndexChange(elements_[0], 0);
  44.     }
  45.     elements_.pop_back();
  46.     SiftDown(0);
  47.   }
  48.   size_t size() const {
  49.     return elements_.size();
  50.   }
  51.   bool empty() const {
  52.     return elements_.empty();
  53.   }
  54.  
  55. private:
  56.   IndexChangeObserver index_change_observer_;
  57.   Compare compare_;
  58.   std::vector<T> elements_;
  59.  
  60.   size_t Parent(size_t index) const {
  61.     if (index != 0)
  62.       return (index - 1) / 2;
  63.     return k_null_index;
  64.   }
  65.   size_t LeftSon(size_t index) const {
  66.     if (2 * index + 1 < size())
  67.       return 2 * index + 1;
  68.     return k_null_index;
  69.   }
  70.   size_t RightSon(size_t index) const {
  71.     if (2 * index + 2 < size())
  72.       return 2 * index + 2;
  73.     return k_null_index;
  74.   }
  75.  
  76.   bool CompareElements(size_t first_index, size_t second_index) const {
  77.     return compare_(elements_[first_index], elements_[second_index]);
  78.   }
  79.   void NotifyIndexChange(const T& element, size_t new_element_index) {
  80.     index_change_observer_(element, new_element_index);
  81.   }
  82.   void SwapElements(size_t first_index, size_t second_index) {
  83.     NotifyIndexChange(elements_[first_index], second_index);
  84.     NotifyIndexChange(elements_[second_index], first_index);
  85.     std::swap(elements_[first_index], elements_[second_index]);
  86.   }
  87.   size_t SiftUp(size_t index) {
  88.     bool tr = true;
  89.     while (tr) {
  90.       size_t parent = Parent(index);
  91.       if (parent == k_null_index)
  92.         break;
  93.       if (CompareElements(index, parent))
  94.         SwapElements(index, parent);
  95.       index = parent;
  96.     }
  97.     return index;
  98.   }
  99.   void SiftDown(size_t index) {
  100.     bool tr = true;
  101.     while (tr) {
  102.       size_t left = LeftSon(index);
  103.       size_t right = RightSon(index);
  104.       size_t swap;
  105.       if (left == k_null_index && right == k_null_index)
  106.         break;
  107.       else if (left == k_null_index && right != k_null_index)
  108.         swap = right;
  109.       else if (left != k_null_index && right == k_null_index)
  110.         swap = left;
  111.       else if (CompareElements(left, right))
  112.         swap = left;
  113.       else
  114.         swap = right;
  115.       if (!CompareElements(index, swap))
  116.         SwapElements(index, swap);
  117.       index = swap;
  118.     }
  119.   }
  120. };
  121.  
  122. struct MemorySegment {
  123.   int left;
  124.   int right;
  125.   size_t heap_index;
  126.  
  127.   MemorySegment(int left, int right) {
  128.     this->left = left;
  129.     this->right = right;
  130.   }
  131.   size_t Size() const {
  132.     return right - left + 1;
  133.   }
  134.   MemorySegment Unite(const MemorySegment& other) const {
  135.     return MemorySegment(std::min(left, other.left), std::max(right, other.right));
  136.   }
  137. };
  138.  
  139. using MemorySegmentIterator = std::list<MemorySegment>::iterator;
  140. using MemorySegmentConstIterator = std::list<MemorySegment>::const_iterator;
  141.  
  142.  
  143. struct MemorySegmentSizeCompare {
  144.   bool operator() (MemorySegmentIterator first, MemorySegmentIterator second) const {
  145.     if ((*first).Size() == (*second).Size())
  146.       return (*first).left <= (*second).left;
  147.     return (*first).Size() > (*second).Size();
  148.   }
  149. };
  150.  
  151.  
  152. using MemorySegmentHeap =
  153. Heap<MemorySegmentIterator, MemorySegmentSizeCompare>;
  154.  
  155.  
  156. struct MemorySegmentsHeapObserver {
  157.   void operator() (MemorySegmentIterator segment, size_t new_index) const {
  158.     (*segment).heap_index = new_index;
  159.   }
  160. };
  161.  
  162. class MemoryManager {
  163. public:
  164.   using Iterator = MemorySegmentIterator;
  165.   using ConstIterator = MemorySegmentConstIterator;
  166.  
  167.   explicit MemoryManager(size_t memory_size) {
  168.     memory_segments_.push_back(MemorySegment(0, memory_size - 1));
  169.     free_memory_segments_.push(memory_segments_.begin());
  170.   }
  171.   Iterator Allocate(size_t size) {
  172.     if (free_memory_segments_.size() == 0)
  173.       return end();
  174.     MemorySegmentIterator it = free_memory_segments_.top();
  175.     if ((*it).Size() >= size) {
  176.       MemorySegment allocated = { (*it).left, (*it).left + static_cast<int>(size) - 1 };
  177.       allocated.heap_index = MemorySegmentHeap::k_null_index;
  178.       MemorySegmentIterator it_allocated = memory_segments_.insert(it, allocated);
  179.       free_memory_segments_.pop();
  180.       if ((*it).Size() != size) {
  181.         (*it).left += size;
  182.         free_memory_segments_.push(it);
  183.       }
  184.       else {
  185.         memory_segments_.erase(it);
  186.       }
  187.       return it_allocated;
  188.     }
  189.     else {
  190.       return end();
  191.     }
  192.   }
  193.   void Free(Iterator position) {
  194.     if (position == end())
  195.       return;
  196.     if (position != std::prev(memory_segments_.end()))
  197.       AppendIfFree(position, std::next(position));
  198.     if (position != memory_segments_.begin())
  199.       AppendIfFree(position, std::prev(position));
  200.     free_memory_segments_.push(position);
  201.   }
  202.   Iterator end() {
  203.     return memory_segments_.end();
  204.   }
  205.  
  206. private:
  207.   MemorySegmentHeap free_memory_segments_ = MemorySegmentHeap(MemorySegmentSizeCompare(),
  208.     MemorySegmentsHeapObserver());
  209.   std::list<MemorySegment> memory_segments_;
  210.  
  211.   void AppendIfFree(Iterator remaining, Iterator appending) {
  212.     if ((*appending).heap_index != MemorySegmentHeap::k_null_index) {
  213.       free_memory_segments_.erase((*appending).heap_index);
  214.       (*remaining) = (*remaining).Unite((*appending));
  215.       memory_segments_.erase(appending);
  216.     }
  217.   }
  218. };
  219.  
  220.  
  221. size_t ReadMemorySize(std::istream& stream = std::cin) {
  222.   size_t memory_size;
  223.   stream >> memory_size;
  224.   return memory_size;
  225. }
  226.  
  227. struct AllocationQuery {
  228.   size_t allocation_size;
  229. };
  230.  
  231. struct FreeQuery {
  232.   int allocation_query_index;
  233. };
  234.  
  235. class MemoryManagerQuery {
  236. public:
  237.   explicit MemoryManagerQuery(AllocationQuery allocation_query)
  238.     : query_(new ConcreteQuery<AllocationQuery>(allocation_query)) {
  239.   }
  240.   explicit MemoryManagerQuery(FreeQuery free_query)
  241.     : query_(new ConcreteQuery<FreeQuery>(free_query)) {
  242.   }
  243.  
  244.   const AllocationQuery* AsAllocationQuery() const {
  245.     auto ptr = dynamic_cast<ConcreteQuery<AllocationQuery>*>(query_.get()); //NOLINT
  246.  
  247.     if (ptr)
  248.       return &ptr->body;
  249.     else
  250.       return nullptr;
  251.   }
  252.   const FreeQuery* AsFreeQuery() const {
  253.     auto ptr = dynamic_cast<ConcreteQuery<FreeQuery>*>(query_.get()); //NOLINT
  254.     if (ptr)
  255.       return &(ptr)->body;
  256.     else
  257.       return nullptr;
  258.   }
  259.  
  260. private:
  261.   class AbstractQuery {
  262.   public:
  263.     virtual ~AbstractQuery() {
  264.     }
  265.  
  266.   protected:
  267.     AbstractQuery() {
  268.     }
  269.   };
  270.  
  271.   template <typename T>
  272.   struct ConcreteQuery : public AbstractQuery {
  273.     T body;
  274.  
  275.     explicit ConcreteQuery(T _body)
  276.       : body(std::move(_body)) {
  277.     }
  278.   };
  279.  
  280.   std::unique_ptr<AbstractQuery> query_;
  281. };
  282.  
  283. std::vector<MemoryManagerQuery> ReadMemoryManagerQueries(std::istream& stream = std::cin) {
  284.   int queries_count;
  285.   stream >> queries_count;
  286.   int number;
  287.   std::vector<MemoryManagerQuery> queries_vector;
  288.   for (int i = 0; i < queries_count; ++i) {
  289.     std::cin >> number;
  290.     if (number > 0)
  291.       queries_vector.emplace_back(AllocationQuery({ static_cast<size_t>(number) }));
  292.     else
  293.       queries_vector.emplace_back(FreeQuery({ -number - 1 }));
  294.   }
  295.   return queries_vector;
  296. }
  297.  
  298. struct MemoryManagerAllocationResponse {
  299.   bool success;
  300.   size_t position;
  301.  
  302.   MemoryManagerAllocationResponse(bool success, size_t position) {
  303.     this->success = success;
  304.     this->position = position;
  305.   };
  306. };
  307.  
  308. MemoryManagerAllocationResponse MakeSuccessfulAllocation(size_t position) {
  309.   return MemoryManagerAllocationResponse(true, position);
  310. }
  311.  
  312. MemoryManagerAllocationResponse MakeFailedAllocation() {
  313.   return MemoryManagerAllocationResponse(false, -1);
  314. }
  315.  
  316. std::vector<MemoryManagerAllocationResponse> RunMemoryManager(
  317.   size_t memory_size,
  318.   const std::vector<MemoryManagerQuery>& queries) {
  319.   MemoryManager memory_manager(memory_size);
  320.   std::vector<MemoryManagerAllocationResponse> responses;
  321.   std::vector<MemorySegmentIterator> iterators;
  322.   for (int it = 0; it < queries.size(); ++it) {
  323.     auto allocation_query = queries[it].AsAllocationQuery();
  324.     if (!allocation_query) {
  325.       auto free_query = queries[it].AsFreeQuery();
  326.       memory_manager.Free(iterators[free_query->allocation_query_index]);
  327.       iterators.push_back(memory_manager.end());
  328.     }
  329.     else {
  330.       auto iterator = memory_manager.Allocate(allocation_query->allocation_size);
  331.       iterators.push_back(iterator);
  332.       if (iterator == memory_manager.end())
  333.         responses.emplace_back(MakeFailedAllocation());
  334.       else
  335.         responses.push_back(MakeSuccessfulAllocation((*iterator).left));
  336.     }
  337.   }
  338.   return responses;
  339. }
  340.  
  341. void OutputMemoryManagerResponses(
  342.   const std::vector<MemoryManagerAllocationResponse>& responses,
  343.   std::ostream& ostream = std::cout) {
  344.   for (auto it : responses) {
  345.     if (it.success == true)
  346.       ostream << it.position + 1 << std::endl;
  347.     else
  348.       ostream << "-1" << std::endl;
  349.   }
  350. }
  351.  
  352. int main() {
  353.   std::istream& input_stream = std::cin;
  354.   std::ostream& output_stream = std::cout;
  355.  
  356.   const size_t memory_size = ReadMemorySize(input_stream);
  357.   const std::vector<MemoryManagerQuery> queries =
  358.     ReadMemoryManagerQueries(input_stream);
  359.  
  360.   const std::vector<MemoryManagerAllocationResponse> responses =
  361.     RunMemoryManager(memory_size, queries);
  362.  
  363.   OutputMemoryManagerResponses(responses, output_stream);
  364.  
  365.   return 0;
  366. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement