2019牛客暑期多校训练营(第三场) J LRU management 模拟链表操作

输入n, m,n表示n种操作,m表示最多可以容纳m个串。

第一种操作:先在容器里找是否存在这个串,如果不存在,则添加在末尾,这个串携带了一个值v。

      如果存在,则先把之前存在的那个拿出来,然后在后面添加这个串,注意此时输入的这个v值不管用!!!!,v还是以前的那个v.

第二种操作:先在这个容器内是否存在这个串,如果存在则看v值,v值为-1, 0, 1,分别表示左边那个,自己,右边那个,如果存在则输出那个串携带的v值,不存在则输出invalid.

#include<bits/stdc++.h>

using namespace std;
const int M = 5e5 + 100;
typedef pair<int, int> pii;
//flag表示v值,ind表示是第几个串,如果先出去了再进来算另外一个
int flag[M * 120], ind[M * 120]; int t, n, m, tot; char s[12]; int tree[M * 12][11];
//判断这个串是否出现过与是否已经出去了。下标对应cnt
int vis[M];
//左边,右边。
int le[M], re[M];
//保存v值。下标对应cnt
int ans[M];
容器头元素,尾元素。
int mi, ma; void add(char ch[], int in, int val) { int root = 0, len = strlen(ch); for(int i = 0; i < len; i++) { int id = ch[i] - '0'; if(!tree[root][id]) { memset(tree[tot], 0, sizeof(tree[tot])); ind[tot] = -1; flag[tot] = -1; tree[root][id] = tot++; } root = tree[root][id]; } ind[root] = in; flag[root] = val; } pii findx(char ch[]) { int root = 0, len = strlen(ch); for(int i = 0; i < len; i++) { int id = ch[i] - '0'; root = tree[root][id]; if(!root) return pii(-1, -1); } return pii(ind[root], flag[root]); } int main() { scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); tot = 1; memset(tree[0], 0, sizeof(tree[0])); int opt, v;
    //给串标号,如果出去了再进来也要++.
int cnt = 0;
    //表示容器里有几个元素。
int num = 0; mi = 1, ma = -1; for(int i = 1; i <= n; i++) { scanf("%d%s%d", &opt, s, &v); int tmp = ma; if(opt == 0) { pii p = findx(s); if(p.first == -1 || vis[p.first] == 0) { cnt++; vis[cnt] = 1; le[cnt] = re[cnt] = -1; ans[cnt] = v; add(s, cnt, v); if(tmp != -1) re[tmp] = cnt; le[cnt] = tmp; ma = cnt; num++; printf("%d\n", v); } else { if(p.first == mi) mi = re[mi]; if(num == 1) mi = p.first; printf("%d\n", p.second);
          //注意这个!!!!更之前tmp有关,
if(p.first == ma) continue;
          //链表操作。
if(le[p.first] != -1) re[le[p.first] ] = re[p.first]; if(re[p.first] != -1) le[re[p.first] ] = le[p.first];
          //!!!!因为ma可能更改了,所以之前要特判一下p.first == ma.
if(tmp != -1) re[tmp] = p.first; le[p.first] = tmp; re[p.first] = -1; ma = p.first; } } else { pii p = findx(s); if(p.first != -1 && vis[p.first] == 1) { if(v == 0) printf("%d\n", p.second); else if(v == -1) { if(le[p.first] != -1 && vis[p.first ] == 1) printf("%d\n", ans[le[p.first] ]); else printf("Invalid\n"); } else { if(re[p.first] != -1 && vis[p.first ] == 1) printf("%d\n", ans[re[p.first] ]); else printf("Invalid\n"); } } else printf("Invalid\n"); } if(num > m) { num--;
        //表示出容器。 vis[mi]
= 0; int tm = re[mi]; if(tm != -1) le[tm] = -1; re[mi] = -1; mi = tm; } } } return 0; } /* 1 8 3 0 0101010 1 0 0101011 2 1 0101010 1 0 1100000 3 0 0101011 -1 0 1111111 4 1 0101011 -1 1 0101010 0 */

猜你喜欢

转载自www.cnblogs.com/downrainsun/p/11253564.html