AC自动机的第三个模板

其实,个人觉得,目前我写的这三个不同的模板完全是可以合并在一起求解的。

只是,在这两个无关联的OJ上,同一个AC自动机都可以完成的问题被拆成了三道题而已。

因此,代码只需要略加修改即可解决这道题。

具体题目请上洛谷查看

https://www.luogu.org/problem/show?pid=3796

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. #include<algorithm>
  8. using namespace std;
  9. struct Tree//字典树
  10. {
  11. int fail;//失配指针
  12. int vis[26];//子节点的位置
  13. int end;//标记以这个节点结尾的单词编号
  14. }AC[100000];//Trie树
  15. int cnt=0;//Trie的指针
  16. struct Result
  17. {
  18. int num;
  19. int pos;
  20. }Ans[100000];//所有单词的出现次数
  21. bool operator <(Result a,Result b)
  22. {
  23. if(a.num!=b.num)
  24. return a.num>b.num;
  25. else
  26. return a.pos<b.pos;
  27. }
  28. string s[100000];
  29. inline void Clean(int x)
  30. {
  31. memset(AC[x].vis,0,sizeof(AC[x].vis));
  32. AC[x].fail=0;
  33. AC[x].end=0;
  34. }
  35. inline void Build(string s,int Num)
  36. {
  37. int l=s.length();
  38. int now=0;//字典树的当前指针
  39. for(int i=0;i<l;++i)//构造Trie树
  40. {
  41. if(AC[now].vis[s[i]-'a']==0)//Trie树没有这个子节点
  42. {
  43. AC[now].vis[s[i]-'a']=++cnt;//构造出来
  44. Clean(cnt);
  45. }
  46. now=AC[now].vis[s[i]-'a'];//向下构造
  47. }
  48. AC[now].end=Num;//标记单词结尾
  49. }
  50. void Get_fail()//构造fail指针
  51. {
  52. queue<int> Q;//队列
  53. for(int i=0;i<26;++i)//第二层的fail指针提前处理一下
  54. {
  55. if(AC[0].vis[i]!=0)
  56. {
  57. AC[AC[0].vis[i]].fail=0;//指向根节点
  58. Q.push(AC[0].vis[i]);//压入队列
  59. }
  60. }
  61. while(!Q.empty())//BFS求fail指针
  62. {
  63. int u=Q.front();
  64. Q.pop();
  65. for(int i=0;i<26;++i)//枚举所有子节点
  66. {
  67. if(AC[u].vis[i]!=0)//存在这个子节点
  68. {
  69. AC[AC[u].vis[i]].fail=AC[AC[u].fail].vis[i];
  70. //子节点的fail指针指向当前节点的
  71. //fail指针所指向的节点的相同子节点
  72. Q.push(AC[u].vis[i]);//压入队列
  73. }
  74. else//不存在这个子节点
  75. AC[u].vis[i]=AC[AC[u].fail].vis[i];
  76. //当前节点的这个子节点指向当
  77. //前节点fail指针的这个子节点
  78. }
  79. }
  80. }
  81. int AC_Query(string s)//AC自动机匹配
  82. {
  83. int l=s.length();
  84. int now=0,ans=0;
  85. for(int i=0;i<l;++i)
  86. {
  87. now=AC[now].vis[s[i]-'a'];//向下一层
  88. for(int t=now;t;t=AC[t].fail)//循环求解
  89. Ans[AC[t].end].num++;
  90. }
  91. return ans;
  92. }
  93. int main()
  94. {
  95. int n;
  96. while(233)
  97. {
  98. cin>>n;
  99. if(n==0)break;
  100. cnt=0;
  101. Clean(0);
  102. for(int i=1;i<=n;++i)
  103. {
  104. cin>>s[i];
  105. Ans[i].num=0;
  106. Ans[i].pos=i;
  107. Build(s[i],i);
  108. }
  109. AC[0].fail=0;//结束标志
  110. Get_fail();//求出失配指针
  111. cin>>s[0];//文本串
  112. AC_Query(s[0]);
  113. sort(&Ans[1],&Ans[n+1]);
  114. cout<<Ans[1].num<<endl;
  115. cout<<s[Ans[1].pos]<<endl;
  116. for(int i=2;i<=n;++i)
  117. {
  118. if(Ans[i].num==Ans[i-1].num)
  119. cout<<s[Ans[i].pos]<<endl;
  120. else
  121. break;
  122. }
  123. }
  124. return 0;
  125. }

AC自动机模板3【洛谷3796】的更多相关文章

  1. UVALive-4670 Dominating Patterns / 洛谷 3796 【模板】AC自动机

    https://vjudge.net/problem/UVALive-4670 中文题面:https://www.luogu.org/problem/show?pid=3796 AC自动机模板 注意如 ...

  2. HDU 2222 AC自动机模板题

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

  3. Match:Keywords Search(AC自动机模板)(HDU 2222)

    多模匹配 题目大意:给定很多个字串A,B,C,D,E....,然后再给你目标串str字串,看目标串中出现多少个给定的字串. 经典AC自动机模板题,不多说. #include <iostream& ...

  4. HDU 3065 (AC自动机模板题)

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

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

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

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

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

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

    题意: 给一个文本串和多个模式串,求文本串中一共出现多少次模式串 分析: ac自动机模板,关键是失配函数 #include <map> #include <set> #incl ...

  8. hdu 2222 Keywords Search ac自动机模板

    题目链接 先整理一发ac自动机模板.. #include <iostream> #include <vector> #include <cstdio> #inclu ...

  9. 点分治模板(洛谷P4178 Tree)(树分治,树的重心,容斥原理)

    推荐YCB的总结 推荐你谷ysn等巨佬的详细题解 大致流程-- dfs求出当前树的重心 对当前树内经过重心的路径统计答案(一条路径由两条由重心到其它点的子路径合并而成) 容斥减去不合法情况(两条子路径 ...

  10. KMP与AC自动机模板

    HDU 1711 Number Sequence(KMP模板题) http://acm.hdu.edu.cn/showproblem.php?pid=1711 #include<bits/std ...

随机推荐

  1. 配置 github 上的程序

    最近学习的node.vue的单页模式,看到github (地址:https://github.com/bailicangdu/node-elm)上面有大神做了一个几十页的系统,心想怎么弄到本地研究下 ...

  2. 一个 rsync同步文件脚本

    #/bin/bash cd /root/phone echo "update guanwang phone version" git pull ]; then echo " ...

  3. statement preparestatement CallableStatement

    大家都知道Statement.PrepareStatement 和CallableStatement 对象,其实它们是interface,为什么JDBC2.0中要提供这三个对象呢?对于Statemen ...

  4. js利用闭包封装自定义模块的几种方法

    1.自定义模块: 具有特定功能的js文件 将所有的数据和功能都封装在一个函数的内部 只向外暴露一个包含有n个方法的对象或者函数 模块使用者只需要通过模块暴露的对象调用方法来实现相对应的功能 1.利用函 ...

  5. C#将制定文件夹下的PDF文件合并成一个并输出至指定路径

    /// <summary> /// 将源路径下的PDF合并至目标路径下 /// </summary> /// <param name="SourcePath&q ...

  6. HDU - 1043 A* + 康托 [kuangbin带你飞]专题二

    这题我第一次用的bfs + ELFhash,直接TLE,又换成bfs + 康托还是TLE,5000ms都过不了!!我一直调试,还是TLE,我才发觉应该是方法的问题. 今天早上起床怒学了一波A*算法,因 ...

  7. 【BZOJ3529】【SDOI2014】 数表

    Time Limit: 10 Sec Memory Limit: 512 MB Description ​ 有一张\(n×m\)的数表,其第i行第j列(\(,1 \le i \leq n,1 \le ...

  8. 在SpringBoot中配置定时任务

    前言 之前在spring中使用过定时任务,使用注解的方式配置很方便,在SpringBoot中的配置基本相同,只是原来在spring中的xml文件的一些配置需要改变,在SpringBoot中也非常简单. ...

  9. Centos中hive/hbase/hadoop/mysql实际操作及问题总结

    目录 Hive中文乱码问题 hive和hbase的版本不一致 Ambari hive插入Hbase出错 Hive0.12和Hbase0.96不兼容,重新编译hive0.12.0 hiveserver不 ...

  10. Json序列化、反序列化

    引用 using Newtonsoft.Json; using Newtonsoft.Json.Converters; 把Json字符串反序列化为对象 1.目标对象 = JavaScriptConve ...