#include #include #include #include #include #include #include class StockPrice { private: std::unordered_map m; std::multiset min; int currentTS = -1, currentPrice = -1; public: StockPrice() = default; void update(int timestamp, int price) { if (timestamp >= currentTS) { currentTS = timestamp; currentPrice = price; } if (m.count(timestamp)) { min.erase(min.find(m[timestamp])); } m[timestamp] = price; min.insert(price); } int current() const { return currentPrice; } int maximum() const { return *min.rbegin(); } int minimum() const { return *min.begin(); } }; class StockPriceHashMap { private: int currentTS = -1, currentPrice = -1; bool updatedMax = false, updatedMin = false; int max = -1, min = 0x7FFFFFFF, maxTS = -1, minTS = -1; std::unordered_map m; public: StockPriceHashMap() = default; void update(int timestamp, int price) { if (timestamp >= currentTS) { currentTS = timestamp; currentPrice = price; } m[timestamp] = price; if (price >= max || maxTS == timestamp) updatedMax = true; if (price <= min || minTS == timestamp) updatedMin = true; } int current() const { return currentPrice; } int maximum() { if (!updatedMax) return max; updatedMax = false; max = -1; for (const auto& i : m) { if (i.second > max) { maxTS = i.first; max = i.second; } } return max; } int minimum() { if (!updatedMin) return min; updatedMin = false; min = 0x7FFFFFFF; for (const auto& i : m) { if (i.second < min) { minTS = i.first; min = i.second; } } return min; } }; class StockPriceHeap { std::vector> maxHeap, minHeap; int currentTS = -1, currentPrice = -1; std::unordered_set involvedTS; static constexpr inline int father(int n) { return ((n + 1) >> 1) - 1; } static constexpr inline int LChild(int n) { return ((n + 1) << 1) - 1; } static constexpr inline int RChild(int n) { return (n + 1) << 1; } public: StockPriceHeap() = default; void update(int timestamp, int price) { if (timestamp >= currentTS) { currentTS = timestamp; currentPrice = price; } // Search in minHeap auto f = [timestamp, price, this](std::vector>& heap, auto cmp) { int n = heap.size(), pos = n; if (!this->involvedTS.count(timestamp)) { // insert into heap; heap.emplace_back(timestamp, price); } else { for (int i = 0; i < n; ++i) { if (heap[i].first == timestamp) { if (heap[i].second == price) { // Found not changed, return immediately return; } heap[i].second = price; pos = i; break; } } } // always treat heap as a maximum heap // std::make_heap(heap.begin(), heap.end(), cmp); while (pos && cmp(heap[father(pos)], heap[pos])) { // swap with father std::swap(heap[pos], heap[father(pos)]); pos = father(pos); } while (true) { // swap with children int LR = 0; if (LChild(pos) < n && cmp(heap[pos], heap[LChild(pos)])) LR = -1; if (RChild(pos) < n && cmp(LR ? heap[LChild(pos)] : heap[pos], heap[RChild(pos)])) LR = 1; if (!LR) break; std::swap(heap[pos], LR == 1 ? heap[RChild(pos)] : heap[LChild(pos)]); pos = LR == 1 ? RChild(pos) : LChild(pos); } }; f(minHeap, [](const std::pair& x, const std::pair& y) { return x.second > y.second; }); f(maxHeap, [](const std::pair& x, const std::pair& y) { return x.second < y.second; }); involvedTS.insert(timestamp); } int current() const { return currentPrice; } int maximum() const { return maxHeap[0].second; } int minimum() const { return minHeap[0].second; } }; int main() { StockPrice solver; /* solver.update(1, 10); solver.update(2, 5); std::cout << "Current = " << solver.current() << std::endl; std::cout << "Maximum = " << solver.maximum() << std::endl; solver.update(1, 3); std::cout << "Maximum = " << solver.maximum() << std::endl; solver.update(4, 2); std::cout << "Minimum = " << solver.minimum() << std::endl; */ auto begin = std::chrono::high_resolution_clock::now(); for (int i = 1; i <= 20000; ++i) { solver.update(i, i); } for (int i = 1; i <= 10000; ++i) { solver.update(i << 1, 1000000000); solver.maximum(); solver.update((i << 1) + 1, 1000000000); solver.minimum(); } auto end = std::chrono::high_resolution_clock::now(); std::cout << "Time elapsed: " << std::chrono::duration_cast(end - begin).count() << " ms\n"; return 0; }