很简单的题,ac自动机里再维护一个len表示每个状态的串长,用s去query时每到一个结点都要暴力跳fail,因为有可能这个结点不是,但是其fail是危险结点,找到一个就直接break

再用个差分数组快速统计覆盖情况即可

  1. using namespace std;
  2. #define N 1000005
  3.  
  4. char s[N],t[N];
  5. int n,cnt[N];
  6.  
  7. struct Trie{
  8. int nxt[N][],fail[N],end[N],Len[N];
  9. int root,L;
  10. int newnode(){
  11. memset(nxt[L],-,sizeof nxt[L]);
  12. end[L]=;
  13. return L++;
  14. }
  15. void init(){
  16. L=;
  17. root=newnode();
  18. }
  19. void insert(char buf[]){
  20. int len=strlen(buf);
  21. int now=root;
  22. for(int i=;i<len;i++){
  23. if(nxt[now][buf[i]-'a']==-)
  24. nxt[now][buf[i]-'a']=newnode();
  25. now=nxt[now][buf[i]-'a'];
  26. }
  27. end[now]++;Len[now]=len;
  28. }
  29. void build(){
  30. queue<int>q;
  31. fail[root]=root;
  32. for(int i=;i<;i++)
  33. if(nxt[root][i]==-)
  34. nxt[root][i]=root;
  35. else {
  36. fail[nxt[root][i]]=root;
  37. q.push(nxt[root][i]);
  38. }
  39. while(q.size()){
  40. int now=q.front();
  41. q.pop();
  42. for(int i=;i<;i++)
  43. if(nxt[now][i]==-)
  44. nxt[now][i]=nxt[fail[now]][i];
  45. else {
  46. fail[nxt[now][i]]=nxt[fail[now]][i];
  47. q.push(nxt[now][i]);
  48. }
  49. }
  50. }
  51.  
  52. void query(char *s){
  53. int now=root;
  54. int len=strlen(s);
  55. for(int i=;i<len;i++){
  56. if(s[i]<'a' || s[i]>'z'){
  57. now=root;continue;
  58. }
  59. now=nxt[now][s[i]-'a'];
  60. int p=now;
  61. while(p){
  62. if(end[p]){//遇到危险结点了
  63. cnt[i+]--;
  64. cnt[i-Len[p]+]++;
  65. break;
  66. }
  67. p=fail[p];
  68. }
  69. }
  70. }
  71. }ac;
  72.  
  73. int main(){
  74. int tt;cin>>tt;while(tt--){
  75. ac.init();
  76. cin>>n;
  77. for(int i=;i<=n;i++){
  78. scanf("%s",s);
  79. ac.insert(s);
  80. }
  81. ac.build();
  82.  
  83. char ch;
  84. int len=;
  85. getchar();
  86. scanf("%[^\n]%*c",s);
  87. len=strlen(s);
  88.  
  89. for(int i=;i<len;i++){
  90. t[i]=s[i];
  91. if(s[i]>='A' && s[i]<='Z')
  92. s[i]+='a'-'A';
  93. }
  94. t[len]=;
  95.  
  96. for(int i=;i<=len;i++)cnt[i]=;
  97. ac.query(s);
  98. for(int i=;i<len;i++)cnt[i]+=cnt[i-];
  99. for(int i=;i<len;i++){
  100. if(cnt[i]>=)printf("*");
  101. else printf("%c",t[i]);
  102. }
  103.  
  104. puts("");
  105. }
  106. }

ac自动机暴力跳fail匹配——hdu5880的更多相关文章

  1. AC自动机——多个kmp匹配

    (并不能自动AC) 介绍: Aho-Corasick automaton,最经典的处理多个模式串的匹配问题. 是kmp和字典树的结合. 精髓与灵魂: ①利用trie处理多个模式串 ②引入fail指针. ...

  2. 洛谷P2414 阿狸的打字机【AC自动机】【fail树】【dfs序】【树状数组】

    居然真的遇上了这种蔡队题.瑟瑟发抖. 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 题目描述 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿 ...

  3. [NOI2011][bzoj2434] 阿狸的打字机 [AC自动机+dfs序+fail树+树状数组]

    题面 传送门 正文 最暴力的 最暴力的方法:把所有询问代表的字符串跑一遍kmp然后输出 稍微优化一下:把所有询问保存起来,把模板串相同的合并,求出next然后匹配 但是这两种方法本质没有区别,都是暴力 ...

  4. 【洛谷】3966:[TJOI2013]单词【AC自动机】【fail树】

    P3966 [TJOI2013]单词 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出 ...

  5. Codeforces 590E - Birthday(AC 自动机+Dilworth 定理+二分图匹配)

    题面传送门 AC 自动机有时只是辅助建图的工具,真的 首先看到多串问题,果断建出 AC 自动机.设 \(m=\sum|s_i|\). 不难发现子串的包含关系构成了一个偏序集,于是我们考虑转化为图论,若 ...

  6. AC 自动机学习笔记

    虽然 NOIp 原地爆炸了,目前进入 AFO 状态,但感觉省选还是要冲一把,所以现在又来开始颓字符串辣 首先先复习一个很早很早就学过但忘记的算法--自动 AC AC自动机. AC 自动机能够在 \(\ ...

  7. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)

    吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ...

  8. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机+map维护Trie树)

    题目大意:略 由于字符集大,要用map维护Trie树 并不能用AC自动机的Trie图优化,不然内存会炸 所以我用AC自动机暴跳fail水过的 显然根据喵星人建AC自动机是不行的,所以要根据问题建 然而 ...

  9. ac自动机fail树上按询问建立上跳指针——cf963D

    解法看着吓人,其实就是为了优化ac自动机上暴力跳fail指针.. 另外这题对于复杂度的分析很有学习价值 /* 给定一个母串s,再给定n个询问(k,m) 对于每个询问,求出长度最小的t,使t是s的子串, ...

随机推荐

  1. 【MVC】Spring WebFlux

    一.什么是 Spring WebFlux 下图截自 Spring Boot 官方网站: 结合上图,在了解 Spring WebFlux 之前,我们先来对比说说什么是 Spring MVC,这更有益我们 ...

  2. POJ 1426 Find The Multiple (dfs??!!)

    Description Given a positive integer n, write a program to find out a nonzero multiple m of n whose ...

  3. Linux运维学习网站收藏

    Linux运维之道 1>  http://www.linuxidc.com/      //Linux公社,收藏Linux学习的很多知识 2> http://http://www.jb51 ...

  4. angularjs &登录跳转

    如果要使用$location,$stateParams,那么必须有相应形参controller: function ($rootScope, $http, $scope, $state,$locati ...

  5. 2019 ICPC Asia Nanchang Regional E Eating Plan 离散化+前缀和

    题意: 给你n个盘子,这n个盘子里面分别装着1!到n!重量的食物,对于每一个询问k,找出一个最短的区间,使得区间和 mod 998857459 大于或等于k 盘子数量 n<=1e5 询问次数 m ...

  6. 关于UI自动化测试的思考

    不知不觉,时间过去了二年多,从开始想学习自动化(UI自动化到上手做项目)到上手,到能独立开发一个项目的UI自动化脚本. 一直在学习,边做边学,边看边学.边总结(具体看我的博客,其中大部分都是自己的理解 ...

  7. Qwidget布局操作之QGridLayout(网格布局)

    QMainWindow并没有setLayout()函数,因此不能使用setLayout()函数来设置layout,需要使用间接的方法. 需要做的只是先定义一个QWidget对象,然后使用QMainWi ...

  8. MySQL 时间戳与日期格式的相互转换(转)

    1.UNIX时间戳转换为日期用函数: FROM_UNIXTIME() select FROM_UNIXTIME(1156219870); 输出:2006-08-22 12:11:10 2.日期转换为U ...

  9. 十二、SpringBoot 优雅的集成Spring Security

    前言 至于什么是Spring security ,主要两个作用,用户认证和授权.即我们常说的,用户只有登录了才能进行其他操作,没有登录的话就重定向到登录界面.有的用户有权限执行某一操作,而有的用户不能 ...

  10. java并发编程笔记(三)——线程安全性

    java并发编程笔记(三)--线程安全性 线程安全性: ​ 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现 ...