https://www.luogu.org/problem/show?pid=3121#sub
首先题目看清楚

FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的

这意味着你在找答案时,当一个节点正常访问的时候,你不用去寻找fail;
你只要在匹配失败的时候取fail就好了;
关于fail的意义,可以看我AC自动机的博客;
然后我们在造trie时,顺便把一个字符串的长度记录下来;
end=一个字符串的长度;
然后我们开2个栈;
a[]记录当前搜到那个点;
b[]记录当前搜那个char;
然后如果发现当前节点是end;
直接弹出栈顶end个元素;
更新now指针,继续搜;
好了;
有个事情要注意;
我原始的AC自动机;

void makezyy(){for(int i=0;i<26;i++)if(T[0].nxt[i])q[++r]=T[0].nxt[i];while(r>l){int x=q[++l];for(int i=0;i<26;i++)if(T[x].nxt[i]){q[++r]=T[x].nxt[i];int y=T[x].fail;while(y&&!T[y].nxt[i])y=T[y].fail;T[q[r]].fail=T[y].nxt[i];}}
}
void find(int m){int o=0;for(int i=0;i<m;i++){int x=s[i]-'a';int y=o;while(y&&!T[y].nxt[x])y=T[y].fail;o=T[y].nxt[x];a[++tot]=o;b[tot]=i;if(T[o].E){tot-=T[o].E;o=a[tot];}    }
}

大家看,这个好理解,但是用了while循环,会被卡一个点;
那我们看看更优的写法;

void makezyy(){for(int i=0;i<26;i++)if(T[0].nxt[i])q[++r]=T[0].nxt[i];while(r>l){int x=q[++l];for(int i=0;i<26;i++)if(!T[x].nxt[i])T[x].nxt[i]=T[T[x].fail].nxt[i];else{q[++r]=T[x].nxt[i];T[T[x].nxt[i]].fail=T[T[x].fail].nxt[i];}}
}
void find(int m){int o=0;for(int i=0;i<m;i++){o=T[o].nxt[s[i]-'a'];a[++tot]=o;b[tot]=i;if(T[o].E){tot-=T[o].E;o=a[tot];}   }
}

种方法巧妙地运用地推;
两种方法求出的fail值是相同的;
但是这种方法会无法辨别出某个节点在一开始有没有某个儿子;
因为makezyy之后空的儿子自动变成了fail;
好像还可以优化的吧;

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
struct trie{int nxt[26],fail,E;
}T[100005];
int q[100005],l,r,a[100005],b[100005],tot;
int n,m,ll;
char s[100005],c[100005];
void init(int m){int o=0;for(int i=0;i<m;i++){int x=c[i]-'a';if(!T[o].nxt[x])T[o].nxt[x]=++ll;o=T[o].nxt[x];}T[o].E=m;
}
void makezyy(){for(int i=0;i<26;i++)if(T[0].nxt[i])q[++r]=T[0].nxt[i];while(r>l){int x=q[++l];for(int i=0;i<26;i++)if(!T[x].nxt[i])T[x].nxt[i]=T[T[x].fail].nxt[i];else{q[++r]=T[x].nxt[i];T[T[x].nxt[i]].fail=T[T[x].fail].nxt[i];}}
}
void find(int m){int o=0;for(int i=0;i<m;i++){o=T[o].nxt[s[i]-'a'];a[++tot]=o;b[tot]=i;if(T[o].E){tot-=T[o].E;o=a[tot];}   }
}
int main()
{scanf("%s",s);scanf("%d",&n);while(n--)scanf("%s",c),init(strlen(c));makezyy();find(strlen(s));for(int i=1;i<=tot;i++)cout<<s[b[i]];
}

转载于:https://www.cnblogs.com/largecube233/p/6797890.html

AC自动机-洛谷3121 [USACO15FEB]审查(黄金)Censoring (Gold)相关推荐

  1. [洛谷3121]审查

    题目描述 Farmer John has purchased a subscription to Good Hooveskeeping magazine for his cows, so they h ...

  2. 洛谷P3122 [USACO15FEB]圈住牛Fencing the Herd(计算几何+CDQ分治)

    题面 传送门 题解 题目转化一下就是所有点都在直线\(Ax+By-C=0\)的同一侧,也就可以看做所有点代入\(Ax+By-C\)之后的值符号相同,我们只要维护每一个点代入直线之后的最大值和最小值,看 ...

  3. 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)

    题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...

  4. 最小生成树 洛谷P3366【模板】最小生成树 洛谷P2820 局域网

    嗯... 理解生成树的概念: 在一幅图中将所有n个点连接起来的n-1条边所形成的树. 最小生成树: 边权之和最小的生成树. 最小瓶颈生成树: 对于带权图,最大权值最小的生成树. 如何操作? 1.Pri ...

  5. 洛谷 P-4045 密码(AC自动机+状态压缩+数位DP+乱搞)

    洛谷 P-4045 密码 记AC的第一道黑题! 题意:已知一段密码包含了一些字符串,然后求满足条件的密码有多少个,数量小于42时还得全部输出 思路: 一开始WA了两个点,不知道WA的什么,索性把读入的 ...

  6. 洛谷 P3041 视频游戏的连击Video Game Combos(AC自动机+拓扑排序+数位DP)

    洛谷 P3041 视频游戏的连击Video Game Combos 难度一般,不过这个数位DP其实应该叫做记忆化搜索 题意:玩游戏时可以通过按键组合打出combo技能:然后是已知N个combo的按键方 ...

  7. 洛谷P5357 - 【模板】AC自动机(二次加强版)(AC自动机+fail树)

    题目链接:点击查看 题目大意:给出n个模式串,问在主串中分别出现了多少次 题目分析:如果像以往那样,在匹配的时候fail指针乱跳的话,那么是错误的AC自动机使用方法,时间复杂度也大大上升,接近于暴力的 ...

  8. AC自动机模板(【洛谷3808】)

    题面 题目背景 这是一道简单的AC自动机模版题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 题目描述 给定n个模式串和1个文本串,求有多少个模式串 ...

  9. 【洛谷 P3041】 [USACO12JAN]视频游戏的连击Video Game Combos(AC自动机,dp)

    题目链接 手写一下AC自动机(我可没说我之前不是手写的) Trie上dp,每个点的贡献加上所有是他后缀的串的贡献,也就是这个点到根的fail链的和. #include <cstdio> # ...

最新文章

  1. 套接字选项SO_LINGER
  2. 用泛型实现参数化类型
  3. hdu 1535 spfa
  4. linux和用户账户相关的系统文件
  5. mysql write rows_解析MYSQL BINLOG 二进制格式(5)--WRITE_ROW_EVENT
  6. 用户登录色一句java_SpringBoot中用SpringSecurity实现用户登录并返回其拥有哪些角色...
  7. 模拟监控和真实用户体验监测,选哪个?
  8. 如何删除所有已合并的Git分支?
  9. 九章算术卷第七 盈不足
  10. Linux下将你的程序打包成run文件
  11. 霍兰德SI型如何选专业?霍兰德职业兴趣测试
  12. Python官网无法打开解决方案
  13. 苹果内部应用商店批准/审核 iPhone 应用程序相关流程
  14. 【锂知道】锂电池基本原理解析:充电及放电机制
  15. C语言编程奖学金评定,C语言计算奖学金总额
  16. Android 应用换肤功能(白天黑夜主题切换)
  17. 再见python你好julia_再见,Python2。你好,Python3
  18. html网站统计来访人数,实现网站访问人数统计
  19. 深度学习 pytorch cifar10数据集训练
  20. 亚马逊测评系统软件搭建教程:luminati+候鸟防关联浏览器环境

热门文章

  1. 无法添加类型为“mimeMap”的重复集合项
  2. VB课本基础知识总结
  3. Redis 实现延迟队列?深深被折服!!
  4. 聊聊微服务的隔离和熔断
  5. UNIX:描述符和文件结构
  6. 网络:IP协议与寻址
  7. 【Linux 报错】com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure The las
  8. html中基本选择器的优先级,CSS_CSS中的各种选择器与样式优先级小结,优先级:由高到低(从上到下)- phpStudy...
  9. 数据中心建设模式变革-- 如何采用EPC模式实现快速交付?
  10. 阿里展示首个IDC智能机器人 实现人机合作