AC自动机
Posted TS_Hugh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC自动机相关的知识,希望对你有一定的参考价值。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define L 51 #define LL 100000002 using namespace std; char c[11][L],s[LL]; struct Trie { Trie *ch[26],*fail,*last; int who; Trie() { memset(ch,0,sizeof(ch)); fail=NULL; last=NULL; who=0; } void* operator new(size_t size); }*root,*C,*mempool,*q[L*11]; void* Trie :: operator new(size_t size) { if(C==mempool) { C=new Trie[(1<<15)+10]; mempool=C+(1<<15)+10; } return C++; } int n; inline void insert(char *S,int x) { int len=strlen(S); Trie *now=root; for(int i=0;i<len;i++) { if(now->ch[S[i]-‘a‘]==NULL) now->ch[S[i]-‘a‘]=new Trie; now=now->ch[S[i]-‘a‘]; } now->who=x; } inline void build() { q[0]=root; for(int i=0,j=0;i<=j;i++) for(int l=0;l<26;l++) if(q[i]->ch[l]) { Trie *now=q[i]->fail; while(now&&!now->ch[l])now=now->fail; q[i]->ch[l]->fail=now?now->ch[l]:root; q[++j]=q[i]->ch[l]; q[j]->last=q[j]->fail->who?q[j]->fail:q[j]->fail->last; } } inline void Init() { root=new Trie; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",c[i]); insert(c[i],i); } scanf("%s",s); build(); } int sum[11]; inline void work() { Trie *now=root; for(int i=0;s[i];i++) { int to=s[i]-‘a‘; while(now&&!now->ch[to])now=now->fail; now=now?now->ch[to]:root; for(Trie *Now=now;Now;Now=Now->last) sum[Now->who]++; } } inline void print() { for(int i=1;i<=n;i++) printf("%s %d\n",c[i],sum[i]); } int main() { freopen("ACautomata.in","r",stdin); freopen("ACautomata.out","w",stdout); Init(); work(); print(); return 0; }
以上是关于AC自动机的主要内容,如果未能解决你的问题,请参考以下文章
HDU4057 Rescue the Rabbit(AC自动机+状压DP)
Codeforces 86C Genetic engineering(AC自动机+DP)
POJ1699 Best Sequence(AC自动机+状压DP)