贴一个网上讲AC自动机的博客
AC自动机模板(插入模式串,输出文本串中模式串出现的次数)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> #define maxn 1000100 using namespace std; struct node { int ch[30],vis,fail,num; }t[500100]; int cnt; queue<int>q; void insert(char s[]) { int i,v,u=1,len=strlen(s); for (i=0;i<len;i++) { v=s[i]-'a'; if (!t[u].ch[v]) t[u].ch[v]=++cnt; u=t[u].ch[v]; } t[u].num++; } void getFail() { int i,u,v,fl; for (i=0;i<26;i++) t[0].ch[i]=1; q.push(1); t[1].fail=0; while (!q.empty()) { u=q.front(); q.pop(); for (i=0;i<26;i++) { v=t[u].ch[i]; fl=t[u].fail; if (!v) { t[u].ch[i]=t[fl].ch[i]; continue; } t[v].fail=t[fl].ch[i]; q.push(v); } } } int query(char s[]) { int i,v,u=1,k,ans=0,len=strlen(s); for (i=0;i<len;i++) { v=s[i]-'a'; k=t[u].ch[v]; while (k>1 && !t[k].vis) { ans+=t[k].num; t[k].vis=1; k=t[k].fail; } u=t[u].ch[v]; } return ans; } int main() { int i,T,n; char s[maxn]; scanf("%d",&T); while (T--) { cnt=1; memset(t,0,sizeof(t)); scanf("%d",&n); for (i=0;i<n;i++) { scanf("%s",s); insert(s); } getFail(); scanf("%s",s); printf("%d ",query(s)); } return 0; }
B HDU 6096
AC自动机+dfs(还有一些细节需要搞清楚)
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> #define maxn 30005 using namespace std; struct node { int ch[2],fail,num; }t[maxn]; int cnt,vis[maxn],flag; queue<int>q; void insert(char s[]) { int i,v,u=1,len=strlen(s); for (i=0;i<len;i++) { v=s[i]-'0'; if (!t[u].ch[v]) t[u].ch[v]=++cnt; u=t[u].ch[v]; } t[u].num=1; } void getFail() { int i,u,v,fl; for (i=0;i<2;i++) t[0].ch[i]=1; q.push(1); t[1].fail=0; while (!q.empty()) { u=q.front(); q.pop(); if (t[t[u].fail].num) t[u].num=t[t[u].fail].num; for (i=0;i<2;i++) { v=t[u].ch[i]; fl=t[u].fail; if (!v) { t[u].ch[i]=t[fl].ch[i]; continue; } t[v].fail=t[fl].ch[i]; q.push(v); } } } void dfs(int x) { if (vis[x]) { flag=1; return; } if (flag || t[x].num) return; t[x].num=1;vis[x]=1; dfs(t[x].ch[0]); dfs(t[x].ch[1]); vis[x]=0; } int main() { int i,j,k,n; char s[maxn]; scanf("%d",&n); cnt=1; for (i=0;i<n;i++) { scanf("%s",s); insert(s); } getFail(); flag=0; dfs(1); if (flag) printf("TAK "); else printf("NIE "); return 0; }
AC自动机+动规
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> #define mod 10007 using namespace std; struct node { int ch[30],vis,fail,num; }t[60010]; int cnt,f[60010][105]; queue<int>q; void insert(char s[]) { int i,v,u=1,len=strlen(s); for (i=0;i<len;i++) { v=s[i]-'A'; if (!t[u].ch[v]) t[u].ch[v]=++cnt; u=t[u].ch[v]; } t[u].num=1; } void getFail() { int i,u,v,fl; for (i=0;i<26;i++) t[0].ch[i]=1; q.push(1); t[1].fail=0; while (!q.empty()) { u=q.front(); q.pop(); fl=t[u].fail; for (i=0;i<26;i++) { v=t[u].ch[i]; if (!v) { t[u].ch[i]=t[fl].ch[i]; continue; } t[v].fail=t[fl].ch[i]; q.push(v); } if (t[fl].num) t[u].num=1; } } int main() { int i,j,k,n,m,v,ans=1; char s[105]; cnt=1; scanf("%d%d",&n,&m); for (i=1;i<=n;i++) { scanf("%s",s); insert(s); } getFail(); for (i=1;i<=m;i++) ans=(ans*26)%mod; f[1][0]=1; for (j=1;j<=m;j++) for (i=1;i<=cnt;i++) { if (!f[i][j-1]) continue; for (k=0;k<26;k++) { v=t[i].ch[k]; if (t[v].num) continue; f[v][j]=(f[v][j]+f[i][j-1])%mod; } } for (i=1;i<=cnt;i++) ans=(ans-f[i][m]+mod)%mod; printf("%d ",ans); return 0; }