AC自动机
来源:互联网 发布:我是歌手有网络直播吗 编辑:程序博客网 时间:2024/05/29 09:21
AC自动机:简单版
询问每个字符串是否出现过
为了压缩时间,我们当碰到一个ed结点的时候,
如果该结点没有访问过,我们就按照fail跳一遍
如果该结点之前统计过,我们就不用顺着fail指针再统计了
//这里写代码片#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int N=1000005;int n,ch[N][26],tot=0,word[N];char s[N],w[N]; bool ed[N];int Q[N],tou,wei,cnt[N],fail[N];void build(int bh){ int len=strlen(w); int now=0; for (int i=0;i<len;i++) { int x=w[i]-'a'; if (!ch[now][x]) ch[now][x]=++tot; now=ch[now][x]; } ed[now]=1; word[bh]=now;}void makefail(){ tou=wei=0; for (int i=0;i<26;i++) if (ch[0][i]) Q[++wei]=ch[0][i]; while (tou<wei) { int now=Q[++tou]; for (int i=0;i<26;i++) { if (!ch[now][i]) { ch[now][i]=ch[fail[now]][i]; continue; } Q[++wei]=ch[now][i]; fail[ch[now][i]]=ch[fail[now]][i]; } }}void solve(){ memset(cnt,0,sizeof(cnt)); int len=strlen(s); int now=0,ans=0; for (int i=0;i<len;i++) { int x=s[i]-'a'; while (now&&!ch[now][x]) now=fail[now]; now=ch[now][x]; if (ed[now]&&cnt[now]==0) //cnt=0 第一次访问 { cnt[now]++; int f=now; while (f&&cnt[f]==0) { f=fail[f]; cnt[f]++; } } } for (int i=1;i<=n;i++) if (cnt[word[i]]) ans++; printf("%d",ans);}int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%s",w); build(i); } makefail(); scanf("%s",s); solve(); return 0;}
阅读全文
0 0
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC 自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- mysql数据库练习题
- 【LeetCode】464.Can I Win(Medium)解题报告
- Linux系统学习导图整理
- java SE day16 火推
- 160个CrackMe-第九个
- AC自动机
- css样式总结
- 图形程序设计swing概述
- uva 11582 Colossal Fibonacci Numbers! (斐波那契模除周期性)
- 抓包工具Fiddler的使用说明
- 玩转SpringCloud
- Toast加强版Toasty简单使用
- 组合查询
- 2017.11.8学习心得