Description

  Now Coach Pang is preparing for the Graduate Record Examinations as George did in 2011. At each day, Coach Pang can:

   "+w": learn a word w

   "?p": read a paragraph p, and count the number of learnt words. Formally speaking, count the number of substrings of p which is a learnt words.

  Given the records of N days, help Coach Pang to find the count. For convenience, the characters occured in the words and paragraphs are only '0' and '1'.

 

 

Solution

这题网上大部分题解都是错的,只能说数据太水

首先这题用到AC自动机,如果暴力做每一组询问需要getfail一次,但是这样做也能AC.

考虑合并,我们建立两个AC自动机,保证其中一个大小\(<\sqrt{n}\) 每一次对小的进行getfail,复杂度只有\(O(\sqrt{n})\),如果小的 \(size\) 达到了 \(\sqrt{n}\),考虑暴力合并,复杂度 \(O(\sqrt{n})\)

注意一个细节,一个单词只能学习一次,所以每加一次需要判断之前是否存在,网上大部分都没有做这个

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <cstdio>
  6. #include <queue>
  7. #include <cmath>
  8. #define RG register
  9. #define il inline
  10. #define iter iterator
  11. #define Max(a,b) ((a)>(b)?(a):(b))
  12. #define Min(a,b) ((a)<(b)?(a):(b))
  13. using namespace std;
  14. const int N=100005,M=600005;
  15. int m,kase=0,ans=0,B=100,root=0;char s[M*10];
  16. queue<int>q;
  17. struct Ac{
  18. int size,ch[M][2],fail[M],val[M];
  19. int newnode(){
  20. size++;
  21. ch[size][0]=ch[size][1]=0;
  22. fail[size]=0;val[size]=0;
  23. return size;
  24. }
  25. void clear(){
  26. size=-1;newnode();
  27. }
  28. void ins(char *S){
  29. int x,len=strlen(s),p=root;
  30. for(int i=1;i<len;i++){
  31. x=S[i]-'0';
  32. if(ch[p][x])p=ch[p][x];
  33. else ch[p][x]=newnode(),p=ch[p][x];
  34. }
  35. val[p]|=1;
  36. }
  37. void getfail(){
  38. while(!q.empty())q.pop();
  39. q.push(root);int x,u,v;
  40. while(!q.empty()){
  41. x=q.front();q.pop();
  42. for(int i=0;i<=1;i++){
  43. if(!ch[x][i])continue;
  44. u=fail[x];
  45. while(u && !ch[u][i])u=fail[u];
  46. if(ch[u][i] && ch[u][i]!=ch[x][i])
  47. fail[ch[x][i]]=ch[u][i];
  48. v=ch[x][i];q.push(v);
  49. }
  50. }
  51. }
  52. int query(char *S){
  53. int x,len=strlen(S),p=root,ret=0,u;
  54. for(int i=1;i<len;i++){
  55. x=S[i]-'0';
  56. while(p && !ch[p][x])p=fail[p];
  57. p=ch[p][x];u=p;
  58. while(u)ret+=val[u],u=fail[u];
  59. }
  60. return ret;
  61. }
  62. bool check(char *S){
  63. int len=strlen(S),x,p=root;
  64. for(int i=1;i<len;i++){
  65. x=S[i]-'0';
  66. if(!ch[p][x])return false;
  67. p=ch[p][x];
  68. }
  69. return val[p];
  70. }
  71. }A,C;
  72. void dfs(int art,int crt){
  73. int x;
  74. for(int i=0;i<=1;i++)
  75. if(C.ch[crt][i]){
  76. if(!A.ch[art][i])A.ch[art][i]=A.newnode();
  77. x=A.ch[art][i];A.val[x]|=C.val[C.ch[crt][i]];
  78. dfs(x,C.ch[crt][i]);
  79. }
  80. }
  81. char b[N];
  82. void Moveit(){
  83. int k=ans,len=strlen(s),p=1;
  84. k%=(len-1);
  85. for(int i=1;i<=k;i++)b[i]=s[i];
  86. for(int i=1;k<len-1;i++)s[i]=s[++k];
  87. for(int i=len-(ans%(len-1));i<len;i++)s[i]=b[p++];
  88. }
  89. void work()
  90. {
  91. printf("Case #%d:\n",++kase);
  92. scanf("%d",&m);
  93. A.clear();C.clear();ans=0;
  94. while(m--){
  95. scanf("%s",s);
  96. Moveit();
  97. if(s[0]=='+'){
  98. if(A.check(s) || C.check(s))continue;
  99. C.ins(s);
  100. if(C.size>B){dfs(0,0);A.getfail();C.clear();}
  101. else C.getfail();
  102. }
  103. else ans=A.query(s)+C.query(s),printf("%d\n",ans);
  104. }
  105. }
  106. int main()
  107. {
  108. int T;cin>>T;
  109. while(T--)work();
  110. return 0;
  111. }

HDU 4787 GRE Words Revenge的更多相关文章

  1. [HDU 4787] GRE Words Revenge (AC自动机)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4787 题目大意: 给你若干个单词,查询一篇文章里出现的单词数.. 就是被我水过去的...暴力重建AC自 ...

  2. ●HDU 4787 GRE Words Revenge

    题链: http://acm.hdu.edu.cn/showproblem.php?pid=4787 题解: AC自动机(强制在线构造) 题目大意: 有两种操作, 一种为:+S,表示增加模式串S, 另 ...

  3. HDU 3341 Lost's revenge AC自动机+dp

    Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

  4. GRE Words Revenge AC自动机 二进制分组

    GRE Words Revenge 题意和思路都和上一篇差不多. 有一个区别就是需要移动字符串.关于这个字符串,可以用3次reverse来转换, 前面部分翻转一下, 后面部分翻转一下, 最后整个串翻转 ...

  5. HDU4787 GRE Words Revenge【AC自动机 分块】

    HDU4787 GRE Words Revenge 题意: \(N\)次操作,每次记录一个\(01\)串或者查询一个\(01\)串能匹配多少个记录的串,强制在线 题解: 在线的AC自动机,利用分块来降 ...

  6. HDU4787 GRE Words Revenge(AC自动机 分块 合并)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for ...

  7. HDU 3341 Lost's revenge(AC自动机+DP)

    Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

  8. HDU 5922 Minimum’s Revenge 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)

    Minimum's Revenge Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  9. HDU P3341 Lost's revenge 题解+数据生成器

    Lost and AekdyCoin are friends. They always play "number game"(A boring game based on numb ...

随机推荐

  1. 20162328蔡文琛week07

    学号 2016-2017-2 <程序设计与数据结构>第X周学习总结 教材学习内容总结 多态引用在不同的时候可以指向不同类型的对象. 多态引用在运行时才将方法调用用于它的定义绑定在一起. 引 ...

  2. Python处理图片缩略图

    CPU 密集型任务和 IO 密集型任务分别选择多进程multiprocessing.Pool.map 和多线程库multiprocessing.dummy.Pool.map import os imp ...

  3. C++类型萃取

    stl中的迭代器和C++中的类型萃取: http://www.itnose.net/detail/6487058.html 赐教!

  4. Hibernate与mysql的对应类型

    Hibernate映射类型 Java类型 标准SQL类型  integer  java.lang.Integer  integer  long  java.lang.Long  bigint  sho ...

  5. css变化代码2

    <!DOCTYPE html><html>    <head>        <meta charset="utf-8" />   ...

  6. 深度学习之 mnist 手写数字识别

    深度学习之 mnist 手写数字识别 开始学习深度学习,先来一个手写数字的程序 import numpy as np import os import codecs import torch from ...

  7. 算法题丨3Sum

    描述 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all ...

  8. CSS基础:块级元素与盒模型

    简介 在 HTML4.01 中,元素通常可以分为块级元素( “Block-level element” ) 和内联元素 ( "Inline-level element" ) 两大类 ...

  9. 云计算(2)it 是什么

    2015年,全世界在it上面的花费达到3亿8千亿美金之多. 云数据中心:核心基础架构,云计算的物理载体,提供数据处理.存储和高性能计算支撑,包括服务器.存储.冷却.机房空间和能耗管理等. 超大规模的云 ...

  10. IntelliJ IDEA开发Scala代码,与java集成,maven打包编译

    今天尝试了一下在IntelliJ IDEA里面写Scala代码,并且做到和Java代码相互调用,折腾了一下把过程记录下来. 首先需要给IntelliJ IDEA安装一下Scala的插件,在IDEA的启 ...