输入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 + ;
typedef pair<int, int> pii;
//flag表示v值,ind表示是第几个串,如果先出去了再进来算另外一个
int flag[M * ], ind[M * ];
int t, n, m, tot;
char s[];
int tree[M * ][];
//判断这个串是否出现过与是否已经出去了。下标对应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 = , len = strlen(ch);
for(int i = ; i < len; i++) {
int id = ch[i] - '';
if(!tree[root][id]) {
memset(tree[tot], , sizeof(tree[tot]));
ind[tot] = -;
flag[tot] = -;
tree[root][id] = tot++;
}
root = tree[root][id];
}
ind[root] = in;
flag[root] = val;
} pii findx(char ch[]) {
int root = , len = strlen(ch);
for(int i = ; i < len; i++) {
int id = ch[i] - '';
root = tree[root][id];
if(!root) return pii(-, -);
}
return pii(ind[root], flag[root]);
} int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
tot = ;
memset(tree[], , sizeof(tree[]));
int opt, v;
    //给串标号,如果出去了再进来也要++.
int cnt = ;
    //表示容器里有几个元素。
int num = ;
mi = , ma = -;
for(int i = ; i <= n; i++) {
scanf("%d%s%d", &opt, s, &v);
int tmp = ma;
if(opt == ) {
pii p = findx(s);
if(p.first == - || vis[p.first] == ) {
cnt++;
vis[cnt] = ;
le[cnt] = re[cnt] = -;
ans[cnt] = v;
add(s, cnt, v);
if(tmp != -) re[tmp] = cnt;
le[cnt] = tmp;
ma = cnt;
num++;
printf("%d\n", v);
}
else {
           //更改的是第一个
if(p.first == mi) mi = re[mi];
if(num == ) mi = p.first;
printf("%d\n", p.second);
          //注意这个!!!!更之前tmp有关,可能更改的是最后一个
if(p.first == ma) continue;
          //链表操作。
if(le[p.first] != -) re[le[p.first] ] = re[p.first];
if(re[p.first] != -) le[re[p.first] ] = le[p.first];
          //!!!!因为ma可能更改了,所以之前要特判一下p.first == ma.
if(tmp != -) re[tmp] = p.first;
le[p.first] = tmp;
re[p.first] = -;
ma = p.first;
}
}
else {
pii p = findx(s);
if(p.first != - && vis[p.first] == ) {
if(v == ) printf("%d\n", p.second);
else if(v == -) {
if(le[p.first] != - && vis[p.first ] == ) printf("%d\n", ans[le[p.first] ]);
else printf("Invalid\n");
}
else {
if(re[p.first] != - && vis[p.first ] == ) printf("%d\n", ans[re[p.first] ]);
else printf("Invalid\n");
}
}
else printf("Invalid\n");
}
if(num > m) {
num--;
        //表示出容器。
vis[mi] = ;
int tm = re[mi];
if(tm != -) le[tm] = -;
re[mi] = -;
mi = tm;
}
}
}
return ;
}
/*
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
*/

并查集加速链表操作

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1e5 + ;
unordered_map<int, int> fa; int findfa(int x) {
if (!fa.count(x)) return x;
return fa[x] = findfa(fa[x]);
} int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int n, q;
scanf("%d %d", &n, &q);
int op, x;
while (q--) {
scanf("%d %d", &op, &x);
if (op == ) {
fa[x] = findfa(x + );
} else {
int ans = findfa(x);
if (ans > n) ans = -;
printf("%d\n", ans);
}
}
return ;
}

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

  1. 2019牛客暑期多校训练营(第三场)H题目

    题意:给你一个N×N的矩阵,求最大的子矩阵 满足子矩阵中最大值和最小值之差小于等于m. 思路:这题是求满足条件的最大子矩阵,毫无疑问要遍历所有矩阵,并判断矩阵是某满足这个条件,那么我们大致只要解决两个 ...

  2. 2019牛客暑期多校训练营(第三场)- F Planting Trees

    题目链接:https://ac.nowcoder.com/acm/contest/883/F 题意:给定n×n的矩阵,求最大子矩阵使得子矩阵中最大值和最小值的差值<=M. 思路:先看数据大小,注 ...

  3. 2019牛客暑期多校训练营(第三场) F.Planting Trees(单调队列)

    题意:给你一个n*n的高度矩阵 要你找到里面最大的矩阵且最大的高度差不能超过m 思路:我们首先枚举上下右边界,然后我们可以用单调队列维护一个最左的边界 然后计算最大值 时间复杂度为O(n*n*n) # ...

  4. 2019牛客暑期多校训练营(第六场)J Upgrading Technology

    传送门 题意: 就是给你n个技能,每个技能最高升到m级,每升一级就是耗费Cij钱,这个Cij可能是负的,如果所有技能都升到或者说超过j等级,就会获得Dj钱,这个Dj也有可能是负值,让你求你最多得到多少 ...

  5. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  6. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  7. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  8. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  9. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  10. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

随机推荐

  1. 消息队列和Kafka

    ------20191211闪

  2. Mac 多版本 JDK 管理

    Mac 多版本 JDK 管理 1. 准备 ZSH Homebrew Oracle JDK 1.8 安装包(Homebrew 官方源和第三方源不再提供老版本的 Oracle JDK) 2. 安装 JDK ...

  3. yarn 不要一起用 npm

    yarn 不要一起用 npm 如果一起用,看下lock 的版本一样不,不一样可能会出现问题

  4. Linux下用Bash语言实现判断素数的功能

    题目链接: 题目描述 写一个判断素数的函数,在主函数输入一个整数,输出是否是素数的消息. 输入 一个数 输出 如果是素数输出prime 如果不是输出not prime 样例输入 97 样例输出 pri ...

  5. 【你不知道的javaScript 上卷 笔记3】javaScript中的声明提升表现

    console.log( a ); var a = 2; 执行输出undefined a = 2; var a; console.log( a ); 执行输出2 说明:javaScript 运行时在编 ...

  6. js 获取项目名称

    //获取项目名称function getWebName(){ var pathName = window.location.pathname.substring(1); var webName = p ...

  7. STM 32 内部功能回顾

    EXTI   外部中断 NVIC 嵌套的向量式中断控制器 AHB 是高级高性能内部总线,主要是用在CPU.DMA.DSP(数字信号处理) APB 是外围总线,I2C. 串口 APB 分为高速APB2( ...

  8. 测试准确率计算方法说明 pre.eq(target).float().sum().item()

    测试准确率计算方法说明 pre.eq(target).float().sum().item() 待办 pred = logits.argmax(dim=1) correct += pred.eq(ta ...

  9. python的selenium实现自动登陆

    知道思想,参考其他文档,python的request模块和selenium模块都可以实现get_cookie()和 add_cookie()的功能. 由于现在在学习selenium自动化测试,我选用s ...

  10. linux异常 - 弹出界面 eth0:设备eth0似乎不存在

    问题描述: 用VMware vSphere Client复制虚拟机之后,出现这个问题 解决方法: service network stop service NetworkManager restart