题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3065

题目大意:多个模式串,范围是大写字母。匹配串的字符范围是(0~127)。问匹配串中含有哪几种模式串,且每种模式串出现了多少次。

解题思路

AC自动机模板题。模式串的范围是大写字母,但是匹配串的范围却是(0~127).

如果Trie 开到 128 加上不回收内存,就会MLE。

实际上开到26就行了,find的时候对于c<0||c>26,强制令pos=root出现失配,并开始下一个字符就行了。

cnt记录这个模式串的个数改为这个模式串的index。

find的时候,把找到的index对应的HASH++,进行统计。

注意每次find时,无须修改last->cnt,因为统计模式串的次数必须让模式串走多遍,修改了之后相当于只走了一遍。

  1. #pragma comment(linker, "/STACK:1024000000,1024000000")
  2. #include "cstdio"
  3. #include "cstring"
  4. #include "string"
  5. #include "iostream"
  6. #include "queue"
  7. #include "vector"
  8. #include "algorithm"
  9. using namespace std;
  10. #define maxn 26
  11. int HASH[];
  12. string code[];
  13. struct Trie
  14. {
  15. Trie *next[maxn],*fail;
  16. int cnt;
  17. }*root;
  18. struct status
  19. {
  20. Trie *last;
  21. int cnt;
  22. status(Trie *last,int cnt):last(last),cnt(cnt) {}
  23. };
  24. Trie *newnode()
  25. {
  26. Trie *ret=new Trie;
  27. memset(ret->next,,sizeof(ret->next));
  28. ret->fail=;
  29. ret->cnt=;
  30. return ret;
  31. }
  32. void init() {root=newnode();}
  33. void Insert(string str,int index)
  34. {
  35. Trie *pos=root;
  36. for(int i=;i<str.size();i++)
  37. {
  38. int c=str[i]-'A';
  39. if(!pos->next[c]) pos->next[c]=newnode();
  40. pos=pos->next[c];
  41. }
  42. pos->cnt=index;
  43. }
  44. void getfail()
  45. {
  46. queue<Trie *> Q;
  47. for(int c=;c<maxn;c++)
  48. {
  49. if(root->next[c])
  50. {
  51. root->next[c]->fail=root;
  52. Q.push(root->next[c]);
  53. }
  54. else root->next[c]=root;
  55. }
  56. while(!Q.empty())
  57. {
  58. Trie *x=Q.front();Q.pop();
  59. for(int c=;c<maxn;c++)
  60. {
  61. if(x->next[c])
  62. {
  63. x->next[c]->fail=x->fail->next[c];
  64. Q.push(x->next[c]);
  65. }
  66. else x->next[c]=x->fail->next[c];
  67. }
  68. }
  69. }
  70. void find(string str)
  71. {
  72. Trie *pos=root,*last;
  73. queue<status> Q;
  74. for(int i=;i<str.size();i++)
  75. {
  76. int c=str[i]-'A';last;
  77. if(c<||c>maxn) {pos=root;continue;}
  78. if(pos->next[c])
  79. {
  80. pos=pos->next[c];
  81. last=pos;
  82. while(last->cnt)
  83. {
  84. Q.push(status(last,last->cnt));
  85. HASH[last->cnt]++;
  86. //last->cnt=0; //修改last->cnt
  87. last=last->fail;
  88. }
  89. }
  90. }
  91. }
  92. int main()
  93. {
  94. //freopen("in.txt","r",stdin);
  95. ios::sync_with_stdio(false);
  96. int n,m;
  97. string tt;
  98. while(cin>>n)
  99. {
  100. memset(HASH,,sizeof(HASH));
  101. init();
  102. for(int i=;i<=n;i++)
  103. {
  104. cin>>code[i];
  105. Insert(code[i],i);
  106. }
  107. getfail();
  108. cin>>tt;
  109. find(tt);
  110. for(int i=;i<=n;i++)
  111. {
  112. if(!HASH[i]) continue;
  113. cout<<code[i]<<": "<<HASH[i]<<endl;
  114. }
  115. }
  116. }
2872067 neopenx HDU 3065 Accepted 16056 343 C++ 2469
2014-10-21 16:41:03

HDU 3065 (AC自动机模板题)的更多相关文章

  1. HDU 2222 AC自动机模板题

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...

  2. HDU 2896 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串 ...

  3. HDU 3065 AC自动机 裸题

    中文题题意不再赘述 注意 失配数组 f  初始化一步到位 #include <stdio.h> #include <string.h> #include <queue&g ...

  4. hdu 3065 AC自动机模版题

    题意:输出每个模式串出现的次数,查询的时候呢使用一个数组进行记录就好. 同上题一样的关键点,其他没什么难度了. #include <cstdio> #include <cstring ...

  5. HDU 2222(AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...

  6. hdu 3065 AC自动机

    // hdu 3065 AC自动机 // // 题目大意: // // 给你n个短串,然后给你一个长串,问:各个短串在长串中,出现了多少次 // // 解题思路: // // AC自动机,插入,构建, ...

  7. hdu 3065 AC自动机(各子串出现的次数)

    病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  8. HDU3695(AC自动机模板题)

    题意:给你n个字符串,再给你一个大的字符串A,问你着n个字符串在正的A和反的A里出现多少个? 其实就是AC自动机模板题啊( ╯□╰ ) 正着query一次再反着query一次就好了 /* gyt Li ...

  9. HDu-2896 病毒侵袭,AC自动机模板题!

    病毒侵袭 模板题,不多说了.. 题意:n个不同的字符串分别代表病毒特征,给出m次查询,每次一个字符串(网址),求这个字符串中有几个病毒特征,分别从大到小输出编号,最后输出所有的带病毒网址个数.格式请看 ...

随机推荐

  1. nginx reload

    iwangzheng.com Usage: nginx [-?hvVt] [-s signal] [-c filename] [-p prefix] [-g directives] Options:- ...

  2. C++中的memset()函数 ------------转自:http://www.360doc.com/content/10/1006/18/1704901_58866679.shtml

    memset()函数可以对大内存的分配进行很方便的操作(初始化),所谓“初始化”,当然是指将你定义的变量或申请的空间赋予你所期望的值,例如语句int i=0;就表明定义了一个变量i,并初始化为0:如果 ...

  3. Linux upstart启动方式详解

     Ubuntu从6.10开始逐步用Upstart()代替原来的SysVinit进行服务进程的管理.RHEL(CentOS)也都从版本6开始转用Upstart代替以往的init.d/rcX.d的线性启动 ...

  4. 用php实现百度网盘图片直链的代码分享

    第一种代码:代码量较少通过正则表达式获取百度网盘的文件真实地址,来实现直链的效果 将下面的代码保存为downbd.php 复制代码代码如下: <?php $canshu=$_SERVER[&qu ...

  5. 修改setup.py的源

    方法一: 修改文件 ~/.pydistutils.cfg为: [easy_install] index_url = http://pypi.douban.com/simple 方法二: 直接在setu ...

  6. 【Linux】为啥查某个进程的线程,查出来的所有线程的pid不一样啊

    楼上说的linux线程和进程是一样的,这个说法是错误的. 看了楼主的问题,感觉楼主是被PID给弄混了,线程进程都会有自己的ID,这个ID就叫做PID,PID是不特指进程ID,线程ID也可以叫做PID. ...

  7. sharepoint添加应用程序

  8. sybaseIQ索引类型和使用注意事项

    1. FP(Fast Projection)此索引为默认的索引形式,在创建表时系统自动设置此索引. 特点:用于SELECT.LIKE '%sys%'.SUM(A+B).JOIN操作等语句. 此类型索引 ...

  9. Linux下永久修改主机名

    红帽系列的Linux发行版主机名存放位置是/etc/sysconfig/network,Ubuntu Linux主机名存放位置是/etc/hostname,所以只要修改主机名存放文件便可以永久的修改计 ...

  10. hdu 1022 Train Problem I 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1022 又是一道栈的练习,这次也是没有用到STL中的栈来实现.用来保存操作过程的数组(process[] ...