以上の2019牛オフサマースクールキャンプ(三) - J - LRU管理 - シミュレーション

https://ac.nowcoder.com/acm/contest/883/J

各キャッシュにクエリを訪問する学んだコンピュータのキャッシュ管理LRUアルゴリズムの原理で構成され、このデータ構造の特性によると、クエリは、ページの値と呼ばれる成功し、ページには、キューを削除するために移動させ、尾。それ以外の場合は、直接キューの末尾にページをロードキューがいっぱいになったとき、チーム初のポップアップ除去されます。別の操作は、ページに、または前のページのクエリを呼び出すことである、または失敗した後、その両方が無効な返します。

そして、あなたが達成するための明確なチェーンではなく、その前のページ、次のページに、キューの真ん中の要素を削除することができ、それは二重リストをリンクされています。問題を解決するためのプロセスは、他のデータ構造の加速クエリを使用して特徴付けることができるクエリ、およびリストのボトルネックので。ここでは短い文字列で、トライunordermapまたは維持するために使用することができる「ノードリストに対応する文字列を。」

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
const int maxn = 500010;
const int maxm = 5000010;
const int FAIL = -100;
 
struct ListNode;
 
struct TrieNode {
    TrieNode *ch[10];
    ListNode *lid;
};
 
struct Trie {
    TrieNode tn[maxm], *root;
    int top;
 
    inline void Init() {
        top = 0;
        root = NewNode();
    }
    inline TrieNode *NewNode() {
        for(int i=0;i<10;++i)
            tn[top].ch[i]=nullptr;
        tn[top].lid = nullptr;
        return &tn[top++];
    }
    inline TrieNode *Insert(char *s, ListNode *lid) {
        TrieNode *cur = root;
        int len=strlen(s);
        for(int i = 0; i < len; ++i) {
            int c = s[i] - '0';
            if(!cur->ch[c])
                cur->ch[c] = NewNode();
            cur = cur->ch[c];
        }
        cur->lid = lid;
        return cur;
    }
    inline TrieNode *Query(char *s) {
        TrieNode *cur = root;
        int len=strlen(s);
        for(int i = 0; i < len; ++i) {
            int c = s[i] - '0';
            if(!cur->ch[c])
                return nullptr;
            cur = cur->ch[c];
        }
        return cur;
    }
} T;
 
struct ListNode {
    ListNode *prev, *next;
    int val;
    TrieNode *tid;
};
 
struct List {
    ListNode ln[maxm];
    ListNode *head, *tail;
 
    int top, size;
 
    void Init() {
        //head,tail都是虚拟节点
        top = 0, size = 0;
        head = NewNode(-1, nullptr, nullptr, &ln[1]);
        tail = NewNode(-1, nullptr, &ln[0], nullptr);
    }
 
    ListNode *NewNode(int val, TrieNode *tid, ListNode *prev, ListNode *next) {
        ln[top].val = val;
        ln[top].tid = tid;
        ln[top].prev = prev;
        ln[top].next = next;
        return &ln[top++];
    }
 
    void Append(int val, TrieNode * tid) {
        Insert(val, tid, tail->prev);
    }
 
    void Insert(int val, TrieNode *tid, ListNode *pn) {
        //在pn后面插入
        ListNode *newNode = NewNode(val, tid, pn, pn->next);
        pn->next->prev = newNode;
        pn->next = newNode;
        ++size;
    }
 
    void Delete(ListNode *pn) {
        //删除pn
        pn->prev->next = pn->next;
        pn->next->prev = pn->prev;
        --size;
    }
} L;
 
int M;
char s[105];
 
inline int OP0(int _val) {
    TrieNode *x = T.Query(s);
    int val;
    if(!x||!x->lid) {
        val = _val;
        if(L.size == M) {
            L.head->next->tid->lid = nullptr;
            L.Delete(L.head->next);
        }
        L.Append(val, nullptr);
        L.tail->prev->tid = T.Insert(s, L.tail->prev);
 
    } else {
        ListNode *y = x->lid;
        val = y->val;
        L.Delete(y);
        L.Append(val, x);
        x->lid = L.tail->prev;
    }
    return val;
}
 
inline int OP1(int _val) {
    TrieNode *x = T.Query(s);
    if(!x)
        return FAIL;
    ListNode *y = x->lid;
    if(!y)
        return FAIL;
    if(_val > 0) {
        y = y->next;
        if(y == L.tail)
            return FAIL;
        return y->val;
    }
    if(_val < 0) {
        y = y->prev;
        if(y == L.head)
            return FAIL;
        return y->val;
    }
    return y->val;
}
 
int main() {
#ifdef local
    freopen("a.txt", "r", stdin);
#endif // Yinku
    int t, q, op, v;
    scanf("%d", &t);
    while(t--) {
        T.Init();
        L.Init();
        scanf("%d%d", &q, &M);
        for(int i = 0; i < q; ++i) {
            scanf("%d%s%d", &op, s, &v);
            if(!op)
                printf("%d\n", OP0(v));
            else {
                int ans = OP1(v);
                if(ans == FAIL)
                    puts("Invalid");
                else
                    printf("%d\n", ans);
            }
        }
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/Yinku/p/11250182.html