You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

164 lines
3.9 KiB

  1. #include <algorithm>
  2. #include <chrono>
  3. #include <deque>
  4. #include <functional>
  5. #include <iomanip>
  6. #include <iostream>
  7. #include <list>
  8. #include <map>
  9. #include <sstream>
  10. #include <unordered_map>
  11. #include <vector>
  12. #define MaxN 2147483647
  13. #define MinN -1
  14. template <typename K, typename V>
  15. class Obj {
  16. public:
  17. K k;
  18. V v;
  19. Obj() {}
  20. Obj(K key, V value) : k(key), v(value) {}
  21. bool operator<(const Obj &o) const {
  22. if (k == o.k) return (v < o.v);
  23. return (k < o.k);
  24. }
  25. bool operator>(const Obj &o) const {
  26. if (k == o.k) return (v > o.v);
  27. return (k > o.k);
  28. }
  29. Obj<K, V> operator=(const Obj<K, V> &o) {
  30. k = o.k;
  31. v = o.v;
  32. return *this;
  33. }
  34. bool operator==(const Obj<K, V> &o) {
  35. if (k == o.k && v == o.v)
  36. return true;
  37. return false;
  38. }
  39. };
  40. template <typename K, typename V>
  41. class IPriorityQueue {
  42. virtual void insert(const Obj<K, V> &item) = 0;
  43. virtual Obj<K, V> findMin() = 0;
  44. virtual Obj<K, V> extractMin() = 0;
  45. virtual void decreaseKey(Obj<K, V> &item, K newKey) = 0;
  46. virtual void remove(Obj<K, V> &item) = 0;
  47. virtual void unite(Obj<K, V> &anotherQueue) = 0;
  48. };
  49. template <typename K, typename V>
  50. class PriorityQueue : IPriorityQueue<K, V> {
  51. Obj<K, V> *m_data;
  52. int sz, mxsz;
  53. std::unordered_map<V, int> map;
  54. public:
  55. PriorityQueue<K, V>(int capacity) : sz(0), mxsz(capacity) {
  56. m_data = new Obj<K, V>[capacity]();
  57. }
  58. // get indexes
  59. int parent(int i) { return (i - 1) / 2; }
  60. int left(int i) { return (2 * i + 1); }
  61. int right(int i) { return (2 * i + 2); }
  62. int findId(const Obj<K, V> &item) {
  63. // I used unordered_map to find the index of the item by value
  64. return map[item.v];
  65. }
  66. Obj<K, V> findMin() { return m_data[0]; }
  67. // insert an object. O(logn)
  68. void insert(const Obj<K, V> &item) {
  69. if (sz == mxsz) {
  70. throw "Couldn't insert!";
  71. }
  72. sz++;
  73. int i = sz - 1, j = sz - 1;
  74. m_data[i] = item;
  75. while (i != 0 && m_data[parent(i)] > m_data[i]) {
  76. swap(m_data[i], m_data[parent(i)]);
  77. j = i;
  78. i = parent(i);
  79. if (i == 0)
  80. break;
  81. }
  82. map[item.v] = j;
  83. }
  84. // decrease the key of an object. O(logn)
  85. void decreaseKey(Obj<K, V> &item, K newKey) {
  86. int i = findId(item);
  87. m_data[i].k = newKey;
  88. while (i != 0 && m_data[parent(i)] > m_data[i]) {
  89. swap(m_data[i], m_data[parent(i)]);
  90. i = parent(i);
  91. }
  92. }
  93. // return minimum and pop it from the queue. O(logn)
  94. Obj<K, V> extractMin() {
  95. if (sz <= 0) return Obj<K, V>(MinN, std::string());
  96. if (sz == 1) {
  97. sz--;
  98. return m_data[0];
  99. }
  100. Obj<K, V> root = m_data[0];
  101. m_data[0] = m_data[sz - 1];
  102. sz--;
  103. MinHeapify(0);
  104. return root;
  105. }
  106. // delete the object from the queue. O(logn)
  107. void remove(Obj<K, V> &item) {
  108. decreaseKey(item, K());
  109. extractMin();
  110. }
  111. // stabilize the heap recursively. O(logn)
  112. void MinHeapify(int i) {
  113. int l = left(i);
  114. int r = right(i);
  115. int mn = i;
  116. if (l < sz && m_data[l] < m_data[i]) mn = l;
  117. if (r < sz && m_data[r] < m_data[mn]) mn = r;
  118. if (mn != i) {
  119. swap(m_data[i], m_data[mn]);
  120. MinHeapify(mn);
  121. }
  122. }
  123. void unite(Obj<K, V> &anotherQueue) {}
  124. };
  125. int main() {
  126. int n;
  127. std::cin >> n;
  128. PriorityQueue<int, std::string> q(1000000);
  129. while (n--) {
  130. std::string query, branch;
  131. std::cin >> query;
  132. if (query == "ADD") {
  133. int value;
  134. std::cin >> branch >> value;
  135. q.insert(Obj<int, std::string>(value, branch));
  136. } else {
  137. std::cout << q.extractMin().v << '\n';
  138. }
  139. }
  140. }