- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 48 lines of C++ from the credited upstream file 3116.cpp.
- The implementation visibly relies on sequence storage.
- 5 loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public:3 long long findKthSmallest(vector<int>& coins, int k) {4 const vector<vector<long>> sizeToLcms = getSizeToLcms(coins);5 long l = 0;6 long r = static_cast<long>(k) * ranges::min(coins);7 8 while (l < r) {9 const long m = (l + r) / 2;10 if (numDenominationsNoGreaterThan(sizeToLcms, m) >= k)11 r = m;12 else13 l = m + 1;14 }15 16 return l;17 }18 19 private:20 21 long numDenominationsNoGreaterThan(const vector<vector<long>>& sizeToLcms,22 long m) {23 long res = 0;24 for (int sz = 1; sz < sizeToLcms.size(); ++sz)25 for (const long lcm : sizeToLcms[sz])26 27 res += m / lcm * pow(-1, sz + 1);28 return res;29 };30 31 32 vector<vector<long>> getSizeToLcms(const vector<int>& coins) {33 const int n = coins.size();34 const int maxMask = 1 << n;35 vector<vector<long>> sizeToLcms(n + 1);36 37 for (unsigned mask = 1; mask < maxMask; ++mask) {38 long lcmOfSelectedCoins = 1;39 for (int i = 0; i < n; ++i)40 if (mask >> i & 1)41 lcmOfSelectedCoins = lcm(lcmOfSelectedCoins, coins[i]);42 sizeToLcms[popcount(mask)].push_back(lcmOfSelectedCoins);43 }44 45 return sizeToLcms;46 }47};48