#include<bits/stdc++.h>
struct DLinkNode{
    int key;
    int value;
    DLinkNode* prev;
    DLinkNode* next;
    DLinkNode()
    {
        key=0;
        value=0;
        prev=nullptr;
        next=nullptr;
    }
    DLinkNode(int _key,int _value)
    {
        key=_key;
        value=_value;
        prev=nullptr;
        next=nullptr;
    }
};

class LRUCache{
private:
    int size;
    int capicaty;
    DLinkNode* head;
    DLinkNode* tail;
    unordered_map<int,DLinkNode*>cache;
public:
    LRUCache(int _capicaty):capicaty(_capicaty),size(0)
    {
        head=new DLinkNode();
        tail=new DLinkNode();
        head->next=tail;
        tail->prev=head;
    }

    void set(int key,int value)
    {
        if(!cache.count(key))
        {
            DLinkNode* node = new DLinkNode(key,value);
            addToHead(node);
            cache[key]=node;
            ++size;
            if(size>capicaty)
            {
                DLinkNode* renode = removeTail();
                cache.erase(renode->key);
                --size;
                delete renode;
            }
        }
        else
        {
            DLinkNode* node = cache[key];
            moveToHead(node);
            node->value=value;
            cache[key]=node;
        }
    }

    int get(int key)
    {
        if(!cache.count(key))
            return -1;
        DLinkNode* node = cache[key];
        moveToHead(node);
        cache[key]=node;
        return node->value;
    }

    void deleteNode(DLinkNode* node)
    {
        node->prev->next=node->next;
        node->next->prev=node->prev;
    }

    void addToHead(DLinkNode* node)
    {
        head->next->prev=node;
        node->next=head->next;
        head->next=node;
        node->prev=head;
    }

    DLinkNode* removeTail()
    {
        DLinkNode* node = tail->prev;
        deleteNode(node);
        return node;
    }

    void moveToHead(DLinkNode* node)
    {
        deleteNode(node);
        addToHead(node);
    }
};
class Solution {
public:
    /**
     * lru design
     * @param operators int整型vector<vector<>> the ops
     * @param k int整型 the k
     * @return int整型vector
     */
    vector<int> LRU(vector<vector<int> >& operators, int k) {
        // write code here
        LRUCache cache(k);
        vector<int> res;
        for(int i=0;i<operators.size();i++)
        {
            if(operators[i][0]==1)
                cache.set(operators[i][1],operators[i][2]);
            else
                res.push_back(cache.get(operators[i][1]));
        }
        return res;
    }
};