add: 220123-CN

This commit is contained in:
Lam Haoyin 2022-01-23 18:34:53 +08:00
parent 2a55064908
commit c85522373c
No known key found for this signature in database
GPG Key ID: 8C089CB1A2B7544F
2 changed files with 205 additions and 1 deletions

204
2201/220123-CN.cpp Normal file
View File

@ -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;
}

View File

@ -3,4 +3,4 @@ PROJECT(2201)
SET(CMAKE_CXX_STANDARD 23)
ADD_EXECUTABLE(2201 220122.cpp)
ADD_EXECUTABLE(2201 220123-CN.cpp)