#include <iostream>
#include <unordered_map>
using namespace std;
template <class T>
struct LinkedList{
LinkedList* remove(){
if(l) l->r = r;
if(r) r->l = l;
return this;
}
void insert(LinkedList* &head){
r = head;
l = NULL;
if(head) head->l = this;
head = this;
}
T x;
LinkedList* l;
LinkedList* r;
LinkedList(T X, LinkedList* L=NULL, LinkedList* R=NULL) : x(X), l(L), r(R) {}
};
class LRUCache {
private:
int n;
LinkedList<pair<int,int>> *head;
LinkedList<pair<int,int>> *tail;
unordered_map<int,LinkedList<pair<int,int>>*> h;
public:
LRUCache(int capacity) {
n = capacity;
head = tail = new LinkedList<pair<int,int>>(make_pair(0,0));
}
int get(int key) {
if(h.find(key)==h.end()) return -1;
if(head!=h[key]) h[key]->remove()->insert(head);
return head->x.second;
}
void put(int key, int value) {
if(h.find(key)==h.end()) h[key] = new LinkedList<pair<int,int>>({key,value});
else h[key]->x.second = value;
get(key);
while(h.size()>n){
key = tail->l->remove()->x.first;
delete(h[key]);
h.erase(key);
}
}
};
int main() {
LRUCache cache(2);
cache.put(1, 1);
cache.put(2, 2);
cout<<cache.get(1)<<endl; // returns 1
cache.put(3, 3); // evicts key 2
cout<<cache.get(2)<<endl; // returns -1 (not found)
cache.put(4, 4); // evicts key 1
cout<<cache.get(1)<<endl; // returns -1 (not found)
cout<<cache.get(3)<<endl; // returns 3
cout<<cache.get(4)<<endl; // returns 4
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlIDxjbGFzcyBUPgpzdHJ1Y3QgTGlua2VkTGlzdHsKICAgIExpbmtlZExpc3QqIHJlbW92ZSgpewogICAgICAgIGlmKGwpICAgbC0+ciA9IHI7CiAgICAgICAgaWYocikgICByLT5sID0gbDsKICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIHZvaWQgaW5zZXJ0KExpbmtlZExpc3QqICZoZWFkKXsKICAgICAgICByID0gaGVhZDsKICAgICAgICBsID0gTlVMTDsKICAgICAgICBpZihoZWFkKSAgICBoZWFkLT5sID0gdGhpczsKICAgICAgICBoZWFkID0gdGhpczsKICAgIH0KICAgIFQgeDsKICAgIExpbmtlZExpc3QqIGw7CiAgICBMaW5rZWRMaXN0KiByOwogICAgTGlua2VkTGlzdChUIFgsIExpbmtlZExpc3QqIEw9TlVMTCwgTGlua2VkTGlzdCogUj1OVUxMKSA6IHgoWCksIGwoTCksIHIoUikge30KfTsKCmNsYXNzIExSVUNhY2hlIHsKcHJpdmF0ZToKICAgIGludCBuOwogICAgTGlua2VkTGlzdDxwYWlyPGludCxpbnQ+PiAqaGVhZDsKICAgIExpbmtlZExpc3Q8cGFpcjxpbnQsaW50Pj4gKnRhaWw7CiAgICB1bm9yZGVyZWRfbWFwPGludCxMaW5rZWRMaXN0PHBhaXI8aW50LGludD4+Kj4gaDsKcHVibGljOgogICAgTFJVQ2FjaGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgbiA9IGNhcGFjaXR5OwogICAgICAgIGhlYWQgPSB0YWlsID0gbmV3IExpbmtlZExpc3Q8cGFpcjxpbnQsaW50Pj4obWFrZV9wYWlyKDAsMCkpOwogICAgfQogICAgCiAgICBpbnQgZ2V0KGludCBrZXkpIHsKICAgICAgICBpZihoLmZpbmQoa2V5KT09aC5lbmQoKSkgICAgcmV0dXJuIC0xOwogICAgICAgIGlmKGhlYWQhPWhba2V5XSkgICAgaFtrZXldLT5yZW1vdmUoKS0+aW5zZXJ0KGhlYWQpOwogICAgICAgIHJldHVybiBoZWFkLT54LnNlY29uZDsKICAgIH0KICAgIAogICAgdm9pZCBwdXQoaW50IGtleSwgaW50IHZhbHVlKSB7CiAgICAgICAgaWYoaC5maW5kKGtleSk9PWguZW5kKCkpICAgIGhba2V5XSA9IG5ldyBMaW5rZWRMaXN0PHBhaXI8aW50LGludD4+KHtrZXksdmFsdWV9KTsKICAgICAgICBlbHNlICAgIGhba2V5XS0+eC5zZWNvbmQgPSB2YWx1ZTsKICAgICAgICBnZXQoa2V5KTsKICAgICAgICB3aGlsZShoLnNpemUoKT5uKXsKICAgICAgICAgICAga2V5ID0gdGFpbC0+bC0+cmVtb3ZlKCktPnguZmlyc3Q7CiAgICAgICAgICAgIGRlbGV0ZShoW2tleV0pOwogICAgICAgICAgICBoLmVyYXNlKGtleSk7CiAgICAgICAgfQogICAgfQp9OwppbnQgbWFpbigpIHsKCUxSVUNhY2hlIGNhY2hlKDIpOwoJY2FjaGUucHV0KDEsIDEpOwoJY2FjaGUucHV0KDIsIDIpOwoJY291dDw8Y2FjaGUuZ2V0KDEpPDxlbmRsOwkvLyByZXR1cm5zIDEKCWNhY2hlLnB1dCgzLCAzKTsJCQkvLyBldmljdHMga2V5IDIKCWNvdXQ8PGNhY2hlLmdldCgyKTw8ZW5kbDsJLy8gcmV0dXJucyAtMSAobm90IGZvdW5kKQoJY2FjaGUucHV0KDQsIDQpOwkJCS8vIGV2aWN0cyBrZXkgMQoJY291dDw8Y2FjaGUuZ2V0KDEpPDxlbmRsOwkvLyByZXR1cm5zIC0xIChub3QgZm91bmQpCgljb3V0PDxjYWNoZS5nZXQoMyk8PGVuZGw7CS8vIHJldHVybnMgMwoJY291dDw8Y2FjaGUuZ2V0KDQpPDxlbmRsOwkvLyByZXR1cm5zIDQKCXJldHVybiAwOwp9