K-string

\[Time Limit: 2000 ms\quad Memory Limit: 131072 kB
\]

题意

给出长度为 \(n\) 的字符串,接下来跟着 \(m\) 次操作,每次 \(1\) 操作往字符串末尾加一个 \(char\),\(2\) 操作统计字符串中出现次数 \(\geq K\) 的字符串个数。

思路

统计一个字符串出现个数,可以用 \(dp[father] = \sum dp[u]\),来计算,那么我们可以知道,一个点从本身往根跑的过程,这个 \(dp\) 值是一直在增大的,所以只要跑到某一个地方的 \(dp \geq K\),就可以不往上更新了,这样插入一个字符,更新一次,边更新边统计答案就可以了。(数据比较水,这样暴力在全是 \(a\) 的情况下是会 \(T\) 的)

这题我用结构体数组写 \(sam\) 被卡了,最后换了纯数组的 \(sam\)。\(emmm\)

  1. /***************************************************************
  2. > File Name : a.cpp
  3. > Author : Jiaaaaaaaqi
  4. > Created Time : 2019年06月06日 星期四 00时14分49秒
  5. ***************************************************************/
  6. #include <map>
  7. #include <set>
  8. #include <list>
  9. #include <ctime>
  10. #include <cmath>
  11. #include <stack>
  12. #include <queue>
  13. #include <cfloat>
  14. #include <string>
  15. #include <vector>
  16. #include <cstdio>
  17. #include <bitset>
  18. #include <cstdlib>
  19. #include <cstring>
  20. #include <iostream>
  21. #include <algorithm>
  22. #define lowbit(x) x & (-x)
  23. #define mes(a, b) memset(a, b, sizeof a)
  24. #define fi first
  25. #define se second
  26. #define pii pair<int, int>
  27. typedef unsigned long long int ull;
  28. typedef long long int ll;
  29. const int maxn = 5e5 + 10;
  30. const int maxm = 1e5 + 10;
  31. const ll mod = 1e9 + 7;
  32. const ll INF = 1e18 + 100;
  33. const int inf = 0x3f3f3f3f;
  34. const double pi = acos(-1.0);
  35. const double eps = 1e-8;
  36. using namespace std;
  37. int n, m;
  38. int cas, tol, T;
  39. struct Sam {
  40. int node[maxn][27], fa[maxn], step[maxn];
  41. int dp[maxn];
  42. int sz, last, K, ans;
  43. int newnode() {
  44. mes(node[++sz], 0);
  45. fa[sz] = step[sz] = 0;
  46. dp[sz] = 0;
  47. return sz;
  48. }
  49. void init() {
  50. ans = sz = 0;
  51. last = newnode();
  52. }
  53. void insert(int k) {
  54. int p = last, np = last = newnode();
  55. step[np] = step[p]+1;
  56. for(; p&&!node[p][k]; p=fa[p])
  57. node[p][k] = np;
  58. if(p==0) {
  59. fa[np] = 1;
  60. } else {
  61. int q = node[p][k];
  62. if(step[q] == step[p]+1) {
  63. fa[np] = q;
  64. } else {
  65. int nq = ++sz;
  66. memcpy(node[nq], node[q], sizeof(node[q]));
  67. dp[nq] = dp[q];
  68. fa[nq] = fa[q];
  69. step[nq] = step[p]+1;
  70. fa[np] = fa[q] = nq;
  71. for(; p&&node[p][k]==q; p=fa[p])
  72. node[p][k] = nq;
  73. }
  74. }
  75. }
  76. void update(int p) {
  77. for(; p&&dp[p]<K; p=fa[p]) {
  78. dp[p]++;
  79. if(dp[p]>=K) ans+=step[p]-step[fa[p]];
  80. }
  81. }
  82. } sam;
  83. char s[50005];
  84. int main() {
  85. while(~scanf("%d%d%d", &n, &m, &sam.K)) {
  86. scanf("%s", s+1);
  87. sam.init();
  88. int len = strlen(s+1);
  89. for(int i=1; i<=len; i++) {
  90. sam.insert(s[i]-'a'+1);
  91. sam.update(sam.last);
  92. }
  93. char ss[5];
  94. while(m--) {
  95. int id;
  96. scanf("%d", &id);
  97. if(id == 1) {
  98. scanf("%s", ss+1);
  99. sam.insert(ss[1]-'a'+1);
  100. sam.update(sam.last);
  101. } else {
  102. printf("%d\n", sam.ans);
  103. }
  104. }
  105. }
  106. return 0;
  107. }

K-string HDU - 4641 (后缀自动机)的更多相关文章

  1. HDU 4436 (后缀自动机)

    HDU 4436 str2int Problem : 给若干个数字串,询问这些串的所有本质不同的子串转换成数字之后的和. Solution : 首先将所有串丢进一个后缀自动机.由于这道题询问的是不同的 ...

  2. HDU 4622 (后缀自动机)

    HDU 4622 Reincarnation Problem : 给一个串S(n <= 2000), 有Q个询问(q <= 10000),每次询问一个区间内本质不同的串的个数. Solut ...

  3. HDU 4416 (后缀自动机)

    HDU 4416 Good Article Good sentence Problem : 给一个串S,和一些串T,询问S中有多少个子串没有在T中出现. Solution :首先对所有的T串建立后缀自 ...

  4. Alice's Classified Message HDU - 5558 后缀自动机求某个后缀出现的最早位置

    题意: 给定一个长度不超过 10W 的只包含小写字母的字符串,从下标 0 到 n−1.从下标 0 开始操作, 每次对于下标 pos查找下标 pos 开始的子串中最长的在其他地方出现过的长度,其他出现的 ...

  5. str2int HDU - 4436 后缀自动机求子串信息

    题意: 给出 n 个串,求出这 n 个串所有子串代表的数字的和. 题解; 首先可以把这些串构建后缀自动机(sam.last=1就好了), 因为后缀自动机上从 root走到的任意节点都是一个子串,所有可 ...

  6. 不在B中的A的子串数量 HDU - 4416 (后缀自动机模板题目)

    题目: 给定一个字符串a,又给定一系列b字符串,求字符串a的子串不在b中出现的个数. 题解: 先将所有的查询串放入后缀自动机(每次将sam.last=1)(算出所有子串个数) 然后将母串放入后缀自动机 ...

  7. hdu 6208(后缀自动机、或者AC自动机

    题意:给你n个字符串,问你是否存在一个字符串可以从中找到其他n-1个字符串. 思路:其实很简单,找到最长的那个字符串对他进行匹配,看是否能匹配到n-1个字符串. 可以用AC自动机或者后缀自动机做,但是 ...

  8. HDU 5442 后缀自动机(从环字符串选定一个位置 , 时针或顺时针走一遍,希望得到字典序最大)

    http://acm.hdu.edu.cn/showproblem.php?pid=5442 题目大意: 给定一个字符串,可理解成环,然后选定一位置,逆时针或顺时针走一遍,希望得到字典序最大,如果同样 ...

  9. Boring counting HDU - 3518 后缀自动机

    题意: 对于给出的字符串S, 长度不超过1000, 求其中本质不同的子串的数量, 这些子串满足在字符串S中出现了至少不重合的2次 题解: 将串放入后缀自动机中然后求出每一个节点对应的子串为后缀的子串出 ...

  10. HDU 5442 后缀自动机+kmp

    题目大意: 给定一个字符串,可理解成环,然后选定一位置,逆时针或顺时针走一遍,希望得到字典序最大,如果同样大,希望找到起始位置最小的,如果还相同,就默认顺时针 比赛一直因为处理最小位置出错,一结束就想 ...

随机推荐

  1. 生成Makefile文件全过程

    [1]生成Makefile文件全过程 整体流程如下图: 注意:以下文件根目录为testmake(任意位置新建即可) (1)测试程序 1.1 建立两个目录:mkdir include source 1. ...

  2. NodeJS安装及部署(Linux系统)

    环境说明:Linux环境,CentOS 7版本. 第一步:下载node地址:https://nodejs.org/en/download/ 下载后,是一个[node-v10.16.0-linux-x6 ...

  3. golang --for语句

    一条for 语句可以携带一条for子句. for子句可以包含初始化子句.条件子句.后置子句. package main import ( "fmt" ) func main() { ...

  4. mysql 中的 not like 另一种简化方法。

    第一种 not like 方法 select * from table where `zongbu` not like '%北京%' and `zongbu` not like '%上海%' and ...

  5. Quartz基础调度框架-第二篇服务

    很多应用场景Quartz运行于Windows服务 Conf 在这个基本结构里 是用来存放配置  和上一篇 控制台运行的一样的结构 jobs.xml 的配置清单 <!-- 任务配置--> & ...

  6. C#拼音帮助类

    如果使用此帮助类需要引用 using Microsoft.International.Converters.PinYinConverter; using NPinyin; 可以在NuGet里面下载 1 ...

  7. Lumen 使用事件需要注意的事项

    Lumen 版本 5.2 参考手册 laravel event 需要注意的事项 如果是第一次在lumen下使用事件,需要修改bootstrap\app.php文件 添加对EventServicePro ...

  8. 解决Spring Boot 从1.x升级到 2.x 后 单点登陆(SSO)问题

    解决Spring Boot 从1.x升级到 2.x 后 单点登陆(SSO)问题   在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把Spring S ...

  9. spring 请求参数和路径变量

    请求参数和路径变量:客户端传递参数给服务端的两种方式 请求参数可以发送值传递给服务器,请求参数采用key=value的形式并使用“&”符号进行参数间的分隔,例如: http://localho ...

  10. vue组件6 使用vue添加样式

    class绑定,内联样式 数组语法 :class="[stylename]"    js:data{stylename:classname} 对象语法:class={stylena ...