Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- struct list_section
- {
- int l;
- int r;
- bool isallocated;
- struct list_section* next;
- struct list_section* prev;
- int to_heap;
- };
- struct heap_element
- {
- int l;
- int r;
- int pos;
- list_section* to_list;
- };
- bool operator<(const heap_element& a, const heap_element& b)
- {
- if ((a.r - a.l < b.r - b.l))
- return true;
- if ((a.r - a.l == b.r - b.l) & (a.l > b.l))
- return true;
- return false;
- }
- class Heap
- {
- std::vector<struct heap_element> heap_elements;
- int heap_size;
- public:
- Heap();
- void siftup(int pos);
- void siftdown(int pos);
- void my_swap(int i, int j);
- void add(int, int, list_section*);
- void del(int pos);
- bool isempty();
- heap_element* get_top();
- };
- Heap::Heap()
- {
- std::vector<struct heap_element> heap_elements;
- heap_size = 0;
- }
- heap_element* Heap::get_top()
- {
- return &heap_elements[0];
- }
- bool Heap::isempty()
- {
- if (heap_size == 0)
- return true;
- return false;
- }
- void Heap::my_swap(int i, int j)
- {
- heap_element buffer;
- buffer = heap_elements[i];
- heap_elements[i] = heap_elements[j];
- heap_elements[j] = buffer;
- heap_elements[i].pos = i;
- heap_elements[j].pos = j;
- heap_elements[i].to_list->to_heap = i;
- heap_elements[j].to_list->to_heap = j;
- }
- void Heap::siftup(int pos)
- {
- int curr = pos;
- int parent = (curr - 1) / 2;
- while (parent >= 0 & curr > 0)
- {
- if (heap_elements[parent] < heap_elements[curr])
- my_swap(parent, curr);
- curr = parent;
- parent = (curr - 1) / 2;
- }
- }
- void Heap::siftdown(int pos)
- {
- int parent, max_child;
- int curr = pos;
- int child_l = 2 * curr + 1;
- int child_r = 2 * curr + 2;
- while (child_l < heap_size)
- {
- max_child = child_l;
- if (child_r < heap_size & heap_elements[child_l] < heap_elements[child_r])
- max_child = child_r;
- if (heap_elements[curr] < heap_elements[max_child])
- my_swap(curr, max_child);
- curr = max_child;
- child_l = 2 * curr + 1;
- child_r = 2 * curr + 2;
- }
- }
- void Heap::add(int l, int r, list_section* to_list)
- {
- this->heap_size++;
- heap_element vertex;
- vertex.l = l;
- vertex.r = r;
- vertex.to_list = to_list;
- vertex.pos = heap_size - 1;
- heap_elements.push_back(vertex);
- to_list->to_heap = heap_size - 1;
- siftup(heap_size - 1);
- }
- void Heap::del(int pos)
- {
- heap_elements[pos] = heap_elements[heap_size - 1];
- heap_elements[pos].pos = pos;
- heap_elements[pos].to_list->to_heap = pos;
- heap_elements.pop_back();
- this->heap_size--;
- int parent = (pos - 1) / 2;
- if (heap_elements[parent] < heap_elements[pos])
- siftup(pos);
- else
- siftdown(pos);
- }
- class List
- {
- struct list_section* head;
- int list_size;
- public:
- List();
- list_section* get_head();
- void add_head(int l, int r, bool isallocated, int to_heap);
- void add(int l, int r, bool isallocated, int to_heap, list_section* section);
- void del(list_section* section);
- };
- List::List()
- {
- head = NULL;
- list_size = 0;
- }
- list_section* List::get_head()
- {
- return head;
- }
- void List::add_head(int l, int r, bool isallocated, int to_heap)
- {
- list_section* buffer = new list_section;
- buffer->prev = 0;
- buffer->l = l;
- buffer->r = r;
- buffer->isallocated = isallocated;
- buffer->next = head;
- if (head != NULL)
- head->prev = buffer;
- head = buffer;
- this->list_size++;
- }
- void List::add(int l, int r, bool isallocated, int to_heap, list_section* section)
- {
- list_section* after_section = new list_section;
- after_section->l = l;
- after_section->r = r;
- after_section->isallocated = isallocated;
- after_section->next = section->next;
- after_section->prev = section;
- after_section->to_heap = to_heap;
- if (section->next != NULL)
- section->next->prev = after_section;
- section->next = after_section;
- this->list_size++;
- }
- void List::del(list_section* section)
- {
- if (section->next != NULL)
- section->next->prev = section->prev;
- if (section->prev != NULL)
- section->prev->next = section->next;
- else
- head = section->next;
- delete section;
- }
- int allocate_memory(Heap* heap, List* List, int query, int i, list_section** requests)
- {
- int L, answer;
- heap_element* heap_top;
- heap_top = heap->get_top();
- if (!heap->isempty() & (heap_top->r - heap_top->l + 1) >= query)
- {
- if ((heap_top->r - heap_top->l + 1) == query)
- {
- heap_top->to_list->isallocated = true;
- requests[i] = heap_top->to_list;
- answer = heap_top->l;
- heap->del(0);
- }
- else
- {
- L = heap_top->l;
- heap_top->l = L + query;
- heap_top->to_list->l = L + query;
- int r = L + query - 1;
- bool isallocated = true;
- int to_heap = -1;
- if (heap_top->to_list->prev != NULL)
- {
- List->add(L, r, isallocated, to_heap, heap_top->to_list->prev);
- requests[i] = heap_top->to_list->prev;
- }
- else
- {
- List->add_head(L, r, isallocated, to_heap);
- requests[i] = List->get_head();
- }
- heap->siftdown(0);
- answer = L;
- }
- }
- else
- {
- requests[i] = NULL;
- answer = -1;
- }
- return answer;
- }
- void free_memory(Heap* heap, List* List, int query_num, int i, list_section** requests)
- {
- if (requests[query_num] != NULL)
- {
- requests[query_num]->isallocated = false;
- if (requests[query_num]->prev != NULL)
- {
- if (requests[query_num]->prev->isallocated == false
- & requests[query_num]->prev->r == requests[query_num]->l - 1)
- {
- requests[query_num]->l = requests[query_num]->prev->l;
- heap->del(requests[query_num]->prev->to_heap);
- List->del(requests[query_num]->prev);
- }
- }
- if (requests[query_num]->next != NULL)
- {
- if (requests[query_num]->next->isallocated == false
- & requests[query_num]->next->l - 1 == requests[query_num]->r)
- {
- requests[query_num]->r = requests[query_num]->next->r;
- heap->del(requests[query_num]->next->to_heap);
- List->del(requests[query_num]->next);
- }
- }
- heap->add(requests[query_num]->l, requests[query_num]->r, requests[query_num]);
- requests[query_num] = NULL;
- }
- requests[i] = NULL;
- }
- int main()
- {
- int N, M, query;
- std::cin >> N;
- std::cin >> M;
- Heap heap;
- List List;
- list_section* requests[M];
- List.add_head(1, N, false, 0);
- heap.add(1, N, List.get_head());
- for (int i = 0; i < M; ++i)
- {
- std::cin >> query;
- if (query > 0)
- std::cout << allocate_memory(&heap, &List, query, i, requests) << std::endl;
- else
- free_memory(&heap, &List, -query - 1, i, requests);
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment