Timeline
Timeline
2025-09-20
init
std::set std::distance std::lower_bound std::upper_bound
Problem:
This problem is prone to timeouts, mainly because the timestamps are inherently ordered. If you treat them as unordered, you will basically time out. For example, using a multiset to store timestamps to keep them ordered, but actually a simple vector is sufficient.
Note the std::distance function. Some iterators do not support subtraction, so you can only use this to calculate the distance.
Note that if std::set stores a class or struct, you must implement the comparison operator, because set is ordered.
- std::lower_bound
- Purpose: Returns an iterator to the first element that is greater than or equal (>=) to the specified value. - If the value exists: returns the first position of that value. - If the value does not exist: returns the position of the first element greater than the target value. - If all elements are less than the target value: returns the end() iterator.
Reverse lookup for elements less than the target value: std::lower_the iterator returned by bound minus one, i.e., std::lower_bound(vec.begin(), vec.end(), target) - 1。
- Purpose: Returns an iterator to the first element that is greater than or equal (>=) to the specified value. - If the value exists: returns the first position of that value. - If the value does not exist: returns the position of the first element greater than the target value. - If all elements are less than the target value: returns the end() iterator.
- std::upper_bound
- Purpose: Returns an iterator to the first element greater than (>) the specified value. - If the value exists: skips all equal values and returns the position of the first element greater than the target value. - If the value does not exist: returns the position of the first element greater than the target value. - If all elements are less than or equal to the target value: returns the end() iterator.
Reverse lookup for elements less than or equal to the target value: std::upper_the iterator returned by bound minus one, i.e., std::upper_bound(vec.begin(), vec.end(), target) - 1。
- Purpose: Returns an iterator to the first element greater than (>) the specified value. - If the value exists: skips all equal values and returns the position of the first element greater than the target value. - If the value does not exist: returns the position of the first element greater than the target value. - If all elements are less than or equal to the target value: returns the end() iterator.
Note: when writing operator<
- The parameter must be const Movie& (cannot accept non-const reference).
- The function itself must be const (it will not modify *this).
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 | using std::map;using std::queue;using std::set;using std::vector;class Packet {public: int source; int destination; int timestamp; bool operator<(const Packet &other) const { if (destination != other.destination) return destination < other.destination; if (timestamp != other.timestamp) return timestamp < other.timestamp; return source < other.source; }};class Router {private: set<Packet> router_set; queue<Packet> fifo; // destination->[timestamp array] map<int, vector<int>> router_map; int memoryLimit;public: Router(int memoryLimit) { this->memoryLimit = memoryLimit; } bool addPacket(int source, int destination, int timestamp) { struct Packet newPacket = {source, destination, timestamp}; if (router_set.find(newPacket) != router_set.end()) { return false; } if (router_set.size() >= memoryLimit || fifo.size() >= memoryLimit) { // out of memory Packet s = fifo.front(); fifo.pop(); router_set.erase(s); vector<int> ×tamp_array = router_map[s.destination]; timestamp_array.erase( find(timestamp_array.begin(), timestamp_array.end(), s.timestamp)); } router_set.insert(newPacket); fifo.push(newPacket); router_map[destination].push_back(timestamp); return true; } vector<int> forwardPacket() { vector<int> res; if (fifo.empty()) { return {}; } Packet resPacket = fifo.front(); fifo.pop(); res = {resPacket.source, resPacket.destination, resPacket.timestamp}; router_set.erase(resPacket); vector<int> ×tamp_array = router_map[resPacket.destination]; timestamp_array.erase(find(timestamp_array.begin(), timestamp_array.end(), resPacket.timestamp)); return res; } int getCount(int destination, int startTime, int endTime) { vector<int> &vec = router_map[destination]; return std::distance(std::lower_bound(vec.begin(), vec.end(), startTime), std::upper_bound(vec.begin(), vec.end(), endTime)); }};/** * Your Router object will be instantiated and called as such: * Router* obj = new Router(memoryLimit); * bool param_1 = obj->addPacket(source,destination,timestamp); * vector<int> param_2 = obj->forwardPacket(); * int param_3 = obj->getCount(destination,startTime,endTime); */ |
