题意:给你n个模式串,再给你m个主串,问你每个主串中有多少模式串,并输出是哪些。注意一下,这里给的字符范围是可见字符0~127,所以要开130左右。

思路:用字典树开的时候储存编号,匹配完成后set记录保证不重复和排序。

代码:

  1. #include<cstdio>
  2. #include<vector>
  3. #include<set>
  4. #include<queue>
  5. #include<cstring>
  6. #include<string>
  7. #include<cmath>
  8. #include<cstdlib>
  9. #include<algorithm>
  10. #define ll long long
  11. const int maxn = 5000000+5;
  12. const int maxm = 100000+5;
  13. const int MOD = 1e7;
  14. const int INF = 0x3f3f3f3f;
  15. const int kind = 130;
  16. const char baset = 0;
  17. using namespace std;
  18. struct Trie{
  19. Trie *next[kind];
  20. Trie *fail; //失配值
  21. int sum; //以此为单词结尾的个数
  22. int id;
  23. Trie(){
  24. sum = 0;
  25. memset(next,NULL,sizeof(next));
  26. fail = NULL;
  27. id = 0;
  28. }
  29. };
  30. Trie *root;
  31. queue<Trie *> Q;
  32. int head,tail;
  33. set<int> record;
  34. void Insert(char *s,int id){
  35. Trie *p = root;
  36. for(int i = 0;s[i];i++){
  37. int x = s[i] - baset;
  38. if(p ->next[x] == NULL){
  39. p ->next[x] = new Trie();
  40. }
  41. p = p ->next[x];
  42. }
  43. p ->sum++;
  44. p ->id = id;
  45. }
  46. void buildFail(){ //计算失配值
  47. while(!Q.empty()) Q.pop();
  48. Q.push(root);
  49. Trie *p,*temp;
  50. while(!Q.empty()){
  51. temp = Q.front();
  52. Q.pop();
  53. for(int i = 0;i < kind;i++){
  54. if(temp ->next[i]){
  55. if(temp == root){ //父节点为root,fail为root
  56. temp ->next[i] ->fail = root;
  57. }
  58. else{
  59. p = temp ->fail; //查看父节点的fail
  60. while(p){
  61. if(p ->next[i]){
  62. temp ->next[i] ->fail = p ->next[i];
  63. break;
  64. }
  65. p = p ->fail;
  66. }
  67. if(p == NULL) temp ->next[i] ->fail = root;
  68. }
  69. Q.push(temp ->next[i]);
  70. }
  71. }
  72. }
  73. }
  74. void ac_automation(char *ch){
  75. //p为模式串指针
  76. Trie *p = root;
  77. int len = strlen(ch);
  78. for(int i = 0;i < len;i++){
  79. int x = ch[i] - baset;
  80. while(!p ->next[x] && p != root)
  81. p = p ->fail;
  82. p = p ->next[x]; //找到后p指针指向该结点
  83. if(!p) p = root; //若指针返回为空,则没有找到与之匹配的字符
  84. Trie *temp = p;
  85. while(temp != root){
  86. if(temp ->id > 0)
  87. record.insert(temp ->id);
  88. temp = temp ->fail;
  89. }
  90. }
  91. }
  92. char ch[210];
  93. char s[10005];
  94. int main(){
  95. int n,m,x;
  96. root = new Trie();
  97. scanf("%d",&n);
  98. for(int i = 1;i <= n;i++){
  99. scanf("%s",ch);
  100. Insert(ch,i);
  101. }
  102. buildFail();
  103. int tot = 0;
  104. scanf("%d",&m);
  105. for(int i = 1;i <= m;i++){
  106. record.clear();
  107. scanf("%s",s);
  108. ac_automation(s);
  109. if(record.size()){
  110. tot++;
  111. printf("web %d:",i);
  112. int End = record.size();
  113. for(int j = 1;j <= End;j++){
  114. int id = *record.begin();
  115. printf(" %d",id);
  116. record.erase(id);
  117. }
  118. printf("\n");
  119. }
  120. }
  121. printf("total: %d\n",tot);
  122. return 0;
  123. }

HDU 2896 病毒侵袭(AC自动机)题解的更多相关文章

  1. hdu 2896 病毒侵袭 ac自动机

    /* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...

  2. hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)

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

  3. hdu 2896 病毒侵袭 AC自动机 基础题

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

  4. HDU 2896 病毒侵袭 (AC自己主动机)

    pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...

  5. hdu 2896 病毒侵袭_ac自动机

    题意:略 思路:套用ac自动机模板 #include <iostream> #include<cstdio> #include<cstring> using nam ...

  6. HDU 2896 病毒侵袭 AC自己主动机题解

    本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...

  7. HDU 2896 病毒侵袭(AC自动机水)

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

  8. HDU 2896 病毒侵袭(AC自动机)

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

  9. HDU 2896 病毒侵袭【AC自动机】

    <题目链接> Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一 ...

  10. hdu2896 病毒侵袭 ac自动机

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2896 题目: 病毒侵袭 Time Limit: 2000/1000 MS (Java/Othe ...

随机推荐

  1. LeetCode——Add Digits

    Description: Given a non-negative integer num, repeatedly add all its digits until the result has on ...

  2. JavaIO再回顾

    File类 JavaIO访问文件名和文件检测相关操作 分隔符最好是使用File类提供的File.separator,使程序更加的健壮. File类提供的方法基本上是见名知意,例如getName()就是 ...

  3. [SQL] sql server中如何查看执行效率不高的语句

    sql server中,如果想知道有哪些语句是执行效率不高的,应该如何查看呢?下面就将为您介绍sql server中如何查看执行效率不高的语句,供您参考.在测量功能时,先以下命令清除sql serve ...

  4. Android搜索自动提示功能 AutocompleteTextView

    1.配置main.xml中自动提示控件: <AutoCompleteTextView android:id="@+id/autotv_searchresult" androi ...

  5. OC开发_Storyboard——iPad开发

    iPad开发(Universal Applications) 一.iPad 1.判断是否在iPad上 BOOL iPad = ([[UIDevice currentDevice] userInterf ...

  6. oneThink发生错误,获取当前执行的SQL语句!

    echo D('AnswerInfoView')->getLastSql();die();

  7. SpringBoot实现热加载方式

    一. spring-boot-devtools方式1.在pom.xml中加入以下代码: 2.标识红线的地方加上 3.在设置里面加上自动编译 4.shift+ctrl+alt+/ 这样就可以了! 二.s ...

  8. Lucene.net之解决锁的问题

    public sealed class SearchIndexManager { private static readonly SearchIndexManager searchManager=ne ...

  9. Visual Studio 2017正式版离线安装方法

    Visual Studio 2017 RTM正式版离线安装及介绍. 首先至官网下载:https://www.visualstudio.com/zh-hans/downloads/ VS 2017 正式 ...

  10. Docker企业级仓库Harbor的安装配置与使用

    Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全.标识和管理等,扩展了开源Docker Distribution.作为一个企业级 ...