[The third session of the 2019 Niuke Summer School] J questions LRU management

Topic link

Title

Okay, I haven't actually read this question before. My teammate told me that this question is a mock question, and it's time. Then I went to...
roughly maintain a linear table, and then there are two operations: insert, query
insert, if this value (string) has appeared before, then put the previous value (string) in the linear table table End (delete the original one), but the saved value (int) is still the previous value (int). If it does not appear, it is inserted at the end of the table. If it is found that the length of the linear table exceeds m after insertion, the element of the table header will be popped up.
When querying, if there is this value (string), then query the previous or next of this value (string) according to the requirements, and then return its value (int), if not (there is no previous or next), output: Invalid

analysis

At first I thought this...it should be violent with STL (of course not too violent). I chose unordered_map + list. I
heard that using map will get T, but I haven’t tried it...
unordered_map is a hash table, and map is a red-black tree Relatively speaking, the query, insert, and delete times of the map are relatively stable, all O(logN), while the time uncertainty of unordered_map is relatively large, good luck is O(1) query, bad luck is O(N )

Complexity
is constant on average, and in the worst case linear with container size. ,
Taken from cppreference

unordered_map uses string as an index, and the iterator
list that saves the list saves the order of values, including string and int two variables,
but I actually sent T first, and then added a quick read to AC, and I felt stuck Often...

AC code

#include <bits/stdc++.h>

using namespace std;

typedef list<pair<int, string>>::iterator pl;
unordered_map<string, pl> ump;
list<pair<int, string>> lists;
char catchmessage[100];

struct ioss
{
    
    
#define endl '\n'
    static const int LEN = 20000000;
    char obuf[LEN], *oh = obuf;
    std::streambuf *fb;
    ioss()
    {
    
    
        ios::sync_with_stdio(false);
        cin.tie(NULL);
        cout.tie(NULL);
        fb = cout.rdbuf();
    }
    inline char gc()
    {
    
    

        static char buf[LEN], *s, *t, buf2[LEN];
        return (s == t) && (t = (s = buf) + fread(buf, 1, LEN, stdin)), s == t ? -1 : *s++;
    }
    inline ioss &operator>>(long long &x)
    {
    
    
        static char ch, sgn, *p;
        ch = gc(), sgn = 0;
        for (; !isdigit(ch); ch = gc())
        {
    
    
            if (ch == -1)
                return *this;
            sgn |= ch == '-';
        }
        for (x = 0; isdigit(ch); ch = gc())
            x = x * 10 + (ch ^ '0');
        sgn && (x = -x);
        return *this;
    }
    inline ioss &operator>>(int &x)
    {
    
    
        static char ch, sgn, *p;
        ch = gc(), sgn = 0;
        for (; !isdigit(ch); ch = gc())
        {
    
    
            if (ch == -1)
                return *this;
            sgn |= ch == '-';
        }
        for (x = 0; isdigit(ch); ch = gc())
            x = x * 10 + (ch ^ '0');
        sgn && (x = -x);
        return *this;
    }
    inline ioss &operator>>(char &x)
    {
    
    
        static char ch;
        for (; !isalpha(ch); ch = gc())
        {
    
    
            if (ch == -1)
                return *this;
        }
        x = ch;
        return *this;
    }
    inline ioss &operator>>(string &x)
    {
    
    
        static char ch, *p, buf2[LEN];
        for (; !isalpha(ch) && !isdigit(ch); ch = gc())
            if (ch == -1)
                return *this;
        p = buf2;
        for (; isalpha(ch) || isdigit(ch); ch = gc())
            *p = ch, p++;
        *p = '\0';
        x = buf2;
        return *this;
    }
    inline ioss &operator<<(string &c)
    {
    
    
        for (auto &p : c)
            this->operator<<(p);
        return *this;
    }
    inline ioss &operator<<(const char *c)
    {
    
    
        while (*c != '\0')
        {
    
    
            this->operator<<(*c);
            c++;
        }
        return *this;
    }
    inline ioss &operator<<(const char &c)
    {
    
    
        oh == obuf + LEN ? (fb->sputn(obuf, LEN), oh = obuf) : 0;
        *oh++ = c;
        return *this;
    }
    inline ioss &operator<<(int x)
    {
    
    
        static int buf[30], cnt;
        if (x < 0)
            this->operator<<('-'), x = -x;
        if (x == 0)
            this->operator<<('0');
        for (cnt = 0; x; x /= 10)
            buf[++cnt] = x % 10 | 48;
        while (cnt)
            this->operator<<((char)buf[cnt--]);
        return *this;
    }
    inline ioss &operator<<(long long x)
    {
    
    
        static int buf[30], cnt;
        if (x < 0)
            this->operator<<('-'), x = -x;
        if (x == 0)
            this->operator<<('0');
        for (cnt = 0; x; x /= 10)
            buf[++cnt] = x % 10 | 48;
        while (cnt)
            this->operator<<((char)buf[cnt--]);
        return *this;
    }
    ~ioss()
    {
    
    
        fb->sputn(obuf, oh - obuf);
    }
} io;

int main()
{
    
    
#ifdef ACM_LOCAL
    freopen("./in.txt", "r", stdin);
    freopen("./out.txt", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    int t;
    io >> t;
    while (t--)
    {
    
    
        ump.clear();
        lists.clear();
        int q, m;
        io >> q >> m;
        string s;
        int op, val;
        for (int i = 0; i < q; i++)
        {
    
    
            pl cur;
            io >> op >> s >> val;
            if (op)
            {
    
    
                if (!ump.count(s))
                {
    
    
                    cout << "Invalid" << endl;
                    continue;
                }
                cur = ump[s];
                if (val == 1)
                {
    
    
                    cur++;
                    if (cur == lists.end())
                    {
    
    
                        cout << "Invalid" << endl;
                        continue;
                    }
                }
                else if (val == -1)
                {
    
    
                    if (cur == lists.begin())
                    {
    
    
                        cout << "Invalid" << endl;
                        continue;
                    }
                    cur--;
                }
                cout << (*cur).first << endl;
            }
            else
            {
    
    
                if (!ump.count(s))
                {
    
    
                    pair<int, string> newnode = make_pair(val, s);
                    lists.push_back(newnode);
                    pl tmp = lists.end();
                    tmp--;
                    ump.insert(make_pair(s, tmp));
                    if (lists.size() > m)
                    {
    
    
                        ump.erase(lists.front().second);
                        lists.pop_front();
                    }
                    cout << val << endl;
                    continue;
                }
                cur = ump[s];
                pair<int, string> newnode = make_pair((*cur).first, s);
                lists.push_back(newnode);
                pl tmp = lists.end();
                tmp--;
                ump[s] = tmp;
                lists.erase(cur);
                cout << newnode.first << endl;
            }
        }
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/m0_43448982/article/details/97382483