add: 220123-CN
This commit is contained in:
parent
2a55064908
commit
c85522373c
|
|
@ -0,0 +1,204 @@
|
|||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <unordered_set>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
class StockPrice {
|
||||
private:
|
||||
std::unordered_map<int, int> m;
|
||||
std::multiset<int> 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<int, int> 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<std::pair<int, int>> maxHeap, minHeap;
|
||||
int currentTS = -1, currentPrice = -1;
|
||||
std::unordered_set<int> 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<std::pair<int, int>>& 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<int, int>& x, const std::pair<int, int>& y) { return x.second > y.second; });
|
||||
f(maxHeap, [](const std::pair<int, int>& x, const std::pair<int, int>& 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<std::chrono::milliseconds>(end - begin).count() << " ms\n";
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3,4 +3,4 @@ PROJECT(2201)
|
|||
|
||||
SET(CMAKE_CXX_STANDARD 23)
|
||||
|
||||
ADD_EXECUTABLE(2201 220122.cpp)
|
||||
ADD_EXECUTABLE(2201 220123-CN.cpp)
|
||||
|
|
|
|||
Loading…
Reference in New Issue