之前刷过ac自动机的专辑的题目。。放在那个被封的百度空间里了。。万恶的百度。。。poj上不去了。。试着写一遍这类题目。。。。感觉还好吧。。。
好好理解了fail指针的意义和怎么工作的。。就很好写了。。。建议先看一下这类的讲解。。。网上很多的。。。一定要理解了再去写题。。。
#include<iostream> #include<string> #include<cstdio> #include<queue> using namespace std; #define cc(m,v) memset(m,v,sizeof(m)) #define maxN 300000 struct node{ int n,fail,next[27]; void init(){ fail=-1,n=0,cc(next,0); } }nod[maxN]; int p=0; queue<int> que; void buit(char *s){ int k=0,u; for(;*s;s++,k=nod[k].next[u]) if(nod[k].next[u=(*s-'a')]==0){ nod[k].next[u]=++p; nod[p].init(); } nod[k].n++; } void getfail(){ int i,v,k; for(i=0;i<=26;i++) if(nod[0].next[i]) nod[v=nod[0].next[i]].fail=0,que.push(v); while(!que.empty()){ k=que.front(),que.pop(); for(i=0;i<=26;i++) if(v=nod[k].next[i]) nod[v].fail=nod[nod[k].fail].next[i],que.push(v); else nod[k].next[i]=nod[nod[k].fail].next[i]; } } int getans(char *s){ int i,k=0,sum=0; for(;*s;s++){ i=k=nod[k].next[*s-'a']; while(i>0 && nod[i].n!=-1) sum+=nod[i].n,nod[i].n=-1,i=nod[i].fail; } return sum; } int main(){ int n,m; char ain[10005],as[1000005]; scanf("%d",&n); while(n--){ p=0,nod[0].init(); scanf("%d",&m); while(m--){ scanf("%s",ain); buit(ain); } getfail(); scanf("%s",as); printf("%d\n",getans(as)); } return 0; }