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

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

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

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

  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4. const int M = 5e5 + ;
  5. typedef pair<int, int> pii;
    //flag表示v值,ind表示是第几个串,如果先出去了再进来算另外一个
  6. int flag[M * ], ind[M * ];
  7. int t, n, m, tot;
  8. char s[];
  9. int tree[M * ][];
    //判断这个串是否出现过与是否已经出去了。下标对应cnt
  10. int vis[M];
    //左边,右边。
  11. int le[M], re[M];
    //保存v值。下标对应cnt
  12. int ans[M];
    容器头元素,尾元素。
  13. int mi, ma;
  14.  
  15. void add(char ch[], int in, int val) {
  16. int root = , len = strlen(ch);
  17. for(int i = ; i < len; i++) {
  18. int id = ch[i] - '';
  19. if(!tree[root][id]) {
  20. memset(tree[tot], , sizeof(tree[tot]));
  21. ind[tot] = -;
  22. flag[tot] = -;
  23. tree[root][id] = tot++;
  24. }
  25. root = tree[root][id];
  26. }
  27. ind[root] = in;
  28. flag[root] = val;
  29. }
  30.  
  31. pii findx(char ch[]) {
  32. int root = , len = strlen(ch);
  33. for(int i = ; i < len; i++) {
  34. int id = ch[i] - '';
  35. root = tree[root][id];
  36. if(!root) return pii(-, -);
  37. }
  38. return pii(ind[root], flag[root]);
  39. }
  40.  
  41. int main() {
  42. scanf("%d", &t);
  43. while(t--) {
  44. scanf("%d%d", &n, &m);
  45. tot = ;
  46. memset(tree[], , sizeof(tree[]));
  47. int opt, v;
        //给串标号,如果出去了再进来也要++.
  48. int cnt = ;
        //表示容器里有几个元素。
  49. int num = ;
  50. mi = , ma = -;
  51. for(int i = ; i <= n; i++) {
  52. scanf("%d%s%d", &opt, s, &v);
  53. int tmp = ma;
  54. if(opt == ) {
  55. pii p = findx(s);
  56. if(p.first == - || vis[p.first] == ) {
  57. cnt++;
  58. vis[cnt] = ;
  59. le[cnt] = re[cnt] = -;
  60. ans[cnt] = v;
  61. add(s, cnt, v);
  62. if(tmp != -) re[tmp] = cnt;
  63. le[cnt] = tmp;
  64. ma = cnt;
  65. num++;
  66. printf("%d\n", v);
  67. }
  68. else {
               //更改的是第一个
  69. if(p.first == mi) mi = re[mi];
  70. if(num == ) mi = p.first;
  71. printf("%d\n", p.second);
              //注意这个!!!!更之前tmp有关,可能更改的是最后一个
  72. if(p.first == ma) continue;
              //链表操作。
  73. if(le[p.first] != -) re[le[p.first] ] = re[p.first];
  74. if(re[p.first] != -) le[re[p.first] ] = le[p.first];
              //!!!!因为ma可能更改了,所以之前要特判一下p.first == ma.
  75. if(tmp != -) re[tmp] = p.first;
  76. le[p.first] = tmp;
  77. re[p.first] = -;
  78. ma = p.first;
  79. }
  80. }
  81. else {
  82. pii p = findx(s);
  83. if(p.first != - && vis[p.first] == ) {
  84. if(v == ) printf("%d\n", p.second);
  85. else if(v == -) {
  86. if(le[p.first] != - && vis[p.first ] == ) printf("%d\n", ans[le[p.first] ]);
  87. else printf("Invalid\n");
  88. }
  89. else {
  90. if(re[p.first] != - && vis[p.first ] == ) printf("%d\n", ans[re[p.first] ]);
  91. else printf("Invalid\n");
  92. }
  93. }
  94. else printf("Invalid\n");
  95. }
  96. if(num > m) {
  97. num--;
            //表示出容器。
  98. vis[mi] = ;
  99. int tm = re[mi];
  100. if(tm != -) le[tm] = -;
  101. re[mi] = -;
  102. mi = tm;
  103. }
  104. }
  105. }
  106. return ;
  107. }
  108. /*
  109. 1
  110. 8 3
  111. 0 0101010 1
  112. 0 0101011 2
  113. 1 0101010 1
  114. 0 1100000 3
  115. 0 0101011 -1
  116. 0 1111111 4
  117. 1 0101011 -1
  118. 1 0101010 0
  119. */

并查集加速链表操作

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. const int maxn = 1e5 + ;
  5. unordered_map<int, int> fa;
  6.  
  7. int findfa(int x) {
  8. if (!fa.count(x)) return x;
  9. return fa[x] = findfa(fa[x]);
  10. }
  11.  
  12. int main() {
  13. // freopen("in.txt", "r", stdin);
  14. // freopen("out.txt", "w", stdout);
  15. int n, q;
  16. scanf("%d %d", &n, &q);
  17. int op, x;
  18. while (q--) {
  19. scanf("%d %d", &op, &x);
  20. if (op == ) {
  21. fa[x] = findfa(x + );
  22. } else {
  23. int ans = findfa(x);
  24. if (ans > n) ans = -;
  25. printf("%d\n", ans);
  26. }
  27. }
  28. return ;
  29. }

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. react-父子子孙组件嵌套-context

    方案一 import React from 'react' import ReactTypes from 'prop-types' /* // 最外层的父组件 export default class ...

  2. 在java中调用mockjs生成模拟数据

    一.手写版 在前端有个模拟数据的神器 Mock.js 能生成随机数据,拦截 Ajax 请求,然后我觉得他的这个生成随机数据不错.然后我就到度娘一顿操作,没找到类似的java实现,于是就有了下面的代码: ...

  3. springboot里面的缓存注解

    https://blog.csdn.net/u012240455/article/details/80844361 https://lfvepclr.gitbooks.io/spring-framew ...

  4. Educational Codeforces Round 81 (Rated for Div. 2) 题解

    过了n天补的题解:D AB就不用说了 C. Obtain The String 思路挺简单的,就是贪心,但是直接贪心的复杂度是O(|s|*|t|),会超时,所以需要用到序列自动机 虽然名字很高端但是就 ...

  5. ASP.NET Razor 常用示例

    1.在网页中显示@符号 使用@@即可使编译器不切换到c#,这样在网页中会显示一个@符号. 2.隐式表达式 也就是正常的razor语法,不能包含空格.(除了await 如:<p>@await ...

  6. JDBC获取超出最大连接的连接池对象

  7. 点击事件后根据url保持相应导航高亮

    直接上代码吧!!! HTML页面: <div class="nav"> <ul class="sub-tit"> <li>& ...

  8. wcf接口输出为json格式

    接口定义: [OperationContract] [WebInvoke(UriTemplate = "AddTask?taskId={taskId}&processGuid={pr ...

  9. 电脑出现kernelbase.dll错误的两种解决方法

    KernelBase.dll是Windows操作系统的重要文件,它为各种应用程序提供服务.如果电脑提示kernelbase.dll错误,这该怎么处理?大家可以用电脑自带的防火墙或者是第三方软件来进行故 ...

  10. 【转载】Hibernate映射文件详解

    转自:http://blog.163.com/hzd_love/blog/static/13199988120108265317988/ Hibernate的持久化类和关系数据库之间的映射通常是用一个 ...