/*
QUESTION 2: Minimum LRU Cache Capacity
Problem Statement:
You are given a sequence of item requests.
A cache follows Least Recently Used replacement:
- If the requested item is already in cache, it is a hit.
- Otherwise, it is a miss.
- If the cache is full, the least recently used item is removed.
- Every accessed item becomes most recently used.
Return the smallest cache capacity that produces at least K hits.
If even unlimited cache cannot produce K hits, return -1.
Hard Constraints:
1 <= number of requests <= 100000
1 <= K <= number of requests
Example:
requests = ["x", "y", "x", "z", "y", "x"]
K = 2
Expected Output:
3
Explanation:
With cache size 2, only the second "x" becomes a hit.
With cache size 3, both "x" and "y" can stay long enough to become hits.
Brute Force:
Try every possible cache size.
For each size, simulate LRU and count hits.
Time Complexity:
O(n * unique)
Optimized Approach:
For a repeated item, suppose it appeared earlier at index p and appears again at index i.
This request becomes a hit if the cache can store all distinct items from p to i - 1.
So every repeated request gives one required cache size.
Collect all required sizes, sort them, and take the K-th smallest one.
Use Fenwick Tree to count distinct items in a range.
Time Complexity:
O(n log n)
Space Complexity:
O(n)
*/
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
struct Fenwick {
int n;
vector<int> bit;
Fenwick(int n) : n(n), bit(n + 1, 0) {}
void add(int idx, int val) {
idx++;
while (idx <= n) {
bit[idx] += val;
idx += idx & -idx;
}
}
int sumPrefix(int idx) {
idx++;
int res = 0;
while (idx > 0) {
res += bit[idx];
idx -= idx & -idx;
}
return res;
}
int rangeSum(int l, int r) {
if (l > r) return 0;
return sumPrefix(r) - (l ? sumPrefix(l - 1) : 0);
}
};
int minimumCacheSize(vector<string>& requests, int k) {
int n = requests.size();
unordered_map<string, int> lastPos;
Fenwick fw(n);
vector<int> required;
for (int i = 0; i < n; i++) {
string item = requests[i];
if (lastPos.count(item)) {
int prev = lastPos[item];
int need = fw.rangeSum(prev, i - 1);
required.push_back(need);
fw.add(prev, -1);
}
fw.add(i, 1);
lastPos[item] = i;
}
if ((int)required.size() < k) return -1;
sort(required.begin(), required.end());
return required[k - 1];
}
};
int main() {
Solution sol;
vector<string> requests = {"x", "y", "x", "z", "y", "x"};
int K = 2;
cout << sol.minimumCacheSize(requests, K) << endl;
return 0;
}
LyoKUVVFU1RJT04gMjogTWluaW11bSBMUlUgQ2FjaGUgQ2FwYWNpdHkKClByb2JsZW0gU3RhdGVtZW50OgpZb3UgYXJlIGdpdmVuIGEgc2VxdWVuY2Ugb2YgaXRlbSByZXF1ZXN0cy4KCkEgY2FjaGUgZm9sbG93cyBMZWFzdCBSZWNlbnRseSBVc2VkIHJlcGxhY2VtZW50OgotIElmIHRoZSByZXF1ZXN0ZWQgaXRlbSBpcyBhbHJlYWR5IGluIGNhY2hlLCBpdCBpcyBhIGhpdC4KLSBPdGhlcndpc2UsIGl0IGlzIGEgbWlzcy4KLSBJZiB0aGUgY2FjaGUgaXMgZnVsbCwgdGhlIGxlYXN0IHJlY2VudGx5IHVzZWQgaXRlbSBpcyByZW1vdmVkLgotIEV2ZXJ5IGFjY2Vzc2VkIGl0ZW0gYmVjb21lcyBtb3N0IHJlY2VudGx5IHVzZWQuCgpSZXR1cm4gdGhlIHNtYWxsZXN0IGNhY2hlIGNhcGFjaXR5IHRoYXQgcHJvZHVjZXMgYXQgbGVhc3QgSyBoaXRzLgpJZiBldmVuIHVubGltaXRlZCBjYWNoZSBjYW5ub3QgcHJvZHVjZSBLIGhpdHMsIHJldHVybiAtMS4KCkhhcmQgQ29uc3RyYWludHM6CjEgPD0gbnVtYmVyIG9mIHJlcXVlc3RzIDw9IDEwMDAwMAoxIDw9IEsgPD0gbnVtYmVyIG9mIHJlcXVlc3RzCgpFeGFtcGxlOgpyZXF1ZXN0cyA9IFsieCIsICJ5IiwgIngiLCAieiIsICJ5IiwgIngiXQpLID0gMgoKRXhwZWN0ZWQgT3V0cHV0OgozCgpFeHBsYW5hdGlvbjoKV2l0aCBjYWNoZSBzaXplIDIsIG9ubHkgdGhlIHNlY29uZCAieCIgYmVjb21lcyBhIGhpdC4KV2l0aCBjYWNoZSBzaXplIDMsIGJvdGggIngiIGFuZCAieSIgY2FuIHN0YXkgbG9uZyBlbm91Z2ggdG8gYmVjb21lIGhpdHMuCgpCcnV0ZSBGb3JjZToKVHJ5IGV2ZXJ5IHBvc3NpYmxlIGNhY2hlIHNpemUuCkZvciBlYWNoIHNpemUsIHNpbXVsYXRlIExSVSBhbmQgY291bnQgaGl0cy4KClRpbWUgQ29tcGxleGl0eToKTyhuICogdW5pcXVlKQoKT3B0aW1pemVkIEFwcHJvYWNoOgpGb3IgYSByZXBlYXRlZCBpdGVtLCBzdXBwb3NlIGl0IGFwcGVhcmVkIGVhcmxpZXIgYXQgaW5kZXggcCBhbmQgYXBwZWFycyBhZ2FpbiBhdCBpbmRleCBpLgpUaGlzIHJlcXVlc3QgYmVjb21lcyBhIGhpdCBpZiB0aGUgY2FjaGUgY2FuIHN0b3JlIGFsbCBkaXN0aW5jdCBpdGVtcyBmcm9tIHAgdG8gaSAtIDEuCgpTbyBldmVyeSByZXBlYXRlZCByZXF1ZXN0IGdpdmVzIG9uZSByZXF1aXJlZCBjYWNoZSBzaXplLgpDb2xsZWN0IGFsbCByZXF1aXJlZCBzaXplcywgc29ydCB0aGVtLCBhbmQgdGFrZSB0aGUgSy10aCBzbWFsbGVzdCBvbmUuCgpVc2UgRmVud2ljayBUcmVlIHRvIGNvdW50IGRpc3RpbmN0IGl0ZW1zIGluIGEgcmFuZ2UuCgpUaW1lIENvbXBsZXhpdHk6Ck8obiBsb2cgbikKClNwYWNlIENvbXBsZXhpdHk6Ck8obikKKi8KCiNpbmNsdWRlIDxiaXRzL3N0ZGMrKy5oPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgU29sdXRpb24gewpwdWJsaWM6CiAgICBzdHJ1Y3QgRmVud2ljayB7CiAgICAgICAgaW50IG47CiAgICAgICAgdmVjdG9yPGludD4gYml0OwoKICAgICAgICBGZW53aWNrKGludCBuKSA6IG4obiksIGJpdChuICsgMSwgMCkge30KCiAgICAgICAgdm9pZCBhZGQoaW50IGlkeCwgaW50IHZhbCkgewogICAgICAgICAgICBpZHgrKzsKICAgICAgICAgICAgd2hpbGUgKGlkeCA8PSBuKSB7CiAgICAgICAgICAgICAgICBiaXRbaWR4XSArPSB2YWw7CiAgICAgICAgICAgICAgICBpZHggKz0gaWR4ICYgLWlkeDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50IHN1bVByZWZpeChpbnQgaWR4KSB7CiAgICAgICAgICAgIGlkeCsrOwogICAgICAgICAgICBpbnQgcmVzID0gMDsKCiAgICAgICAgICAgIHdoaWxlIChpZHggPiAwKSB7CiAgICAgICAgICAgICAgICByZXMgKz0gYml0W2lkeF07CiAgICAgICAgICAgICAgICBpZHggLT0gaWR4ICYgLWlkeDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9CgogICAgICAgIGludCByYW5nZVN1bShpbnQgbCwgaW50IHIpIHsKICAgICAgICAgICAgaWYgKGwgPiByKSByZXR1cm4gMDsKICAgICAgICAgICAgcmV0dXJuIHN1bVByZWZpeChyKSAtIChsID8gc3VtUHJlZml4KGwgLSAxKSA6IDApOwogICAgICAgIH0KICAgIH07CgogICAgaW50IG1pbmltdW1DYWNoZVNpemUodmVjdG9yPHN0cmluZz4mIHJlcXVlc3RzLCBpbnQgaykgewogICAgICAgIGludCBuID0gcmVxdWVzdHMuc2l6ZSgpOwoKICAgICAgICB1bm9yZGVyZWRfbWFwPHN0cmluZywgaW50PiBsYXN0UG9zOwogICAgICAgIEZlbndpY2sgZncobik7CgogICAgICAgIHZlY3RvcjxpbnQ+IHJlcXVpcmVkOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgICAgICBzdHJpbmcgaXRlbSA9IHJlcXVlc3RzW2ldOwoKICAgICAgICAgICAgaWYgKGxhc3RQb3MuY291bnQoaXRlbSkpIHsKICAgICAgICAgICAgICAgIGludCBwcmV2ID0gbGFzdFBvc1tpdGVtXTsKCiAgICAgICAgICAgICAgICBpbnQgbmVlZCA9IGZ3LnJhbmdlU3VtKHByZXYsIGkgLSAxKTsKICAgICAgICAgICAgICAgIHJlcXVpcmVkLnB1c2hfYmFjayhuZWVkKTsKCiAgICAgICAgICAgICAgICBmdy5hZGQocHJldiwgLTEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmdy5hZGQoaSwgMSk7CiAgICAgICAgICAgIGxhc3RQb3NbaXRlbV0gPSBpOwogICAgICAgIH0KCiAgICAgICAgaWYgKChpbnQpcmVxdWlyZWQuc2l6ZSgpIDwgaykgcmV0dXJuIC0xOwoKICAgICAgICBzb3J0KHJlcXVpcmVkLmJlZ2luKCksIHJlcXVpcmVkLmVuZCgpKTsKICAgICAgICByZXR1cm4gcmVxdWlyZWRbayAtIDFdOwogICAgfQp9OwoKaW50IG1haW4oKSB7CiAgICBTb2x1dGlvbiBzb2w7CgogICAgdmVjdG9yPHN0cmluZz4gcmVxdWVzdHMgPSB7IngiLCAieSIsICJ4IiwgInoiLCAieSIsICJ4In07CiAgICBpbnQgSyA9IDI7CgogICAgY291dCA8PCBzb2wubWluaW11bUNhY2hlU2l6ZShyZXF1ZXN0cywgSykgPDwgZW5kbDsKCiAgICByZXR1cm4gMDsKfQ==