Continue to pits, out of the mutual test Round 5 after the topic, and began endless pits ...
Before learning AC automata, it is recommended to learn KMP and tire, here only to the introduction
First of all, tire is a tree that each point represents a letter, and then takes a root, from the root to each leaf node path represents a string.
For example, for string aa,at,ac,ag,gg, we can build a tree like this:
Because it is a character, each point on 26 or 256 pointers on the good, convenient operation, real card space to change.
The completion of such a tree is convenient for us to do what prefix query what.
KMP is to give a string A and a string B, and ask if A is a substring of B.
In fact, it is the improvement on the basis of violence, the whole process is this:
To a preprocessing array f[i], which represents the largest one k satisfying f[1...k]=f[i-k+1,i]. (Array starting from 1)
A bitwise comparison, where failure does not return the beginning but returns F[i].
Usually when we are violent, we raise a little, and then one compares. However, for A is "ABC Abd", B is "abc abc Abd" (There is no space in fact, the space is convenient to see how the data is structured), the program will be very foolish not to use the previous comparison data. When using KMP, suppose we now start with the first character of B, to C is not equal to D stop, at this time the violence will move the beginning of a to B to continue the comparison, however KMP found F[6] (that is, d location) = 2, because we are found in the 6th character, the same as before, that is b[ 1...5]=A[1...5], naturally b[4...5]=a[4...5]. From the preprocessing array we find a[1...2]=a[4...5], then it will move the starting point to b[4] position to continue the comparison. It's much faster.
AC automata is to tire our F-array on the side of the bridge, and then go directly to the comparison when encountered, for example:
(Slightly ugly)
For example, to find the above string in the agg, and found that when the comparison AG is completed, G points to the other G, then we can run directly over it.
Template title (HDU 2222):
#include <queue>#include<cstdio>#include<cstring>#include<algorithm>using namespacestd;structtree{intw,f; intt[ -];} t[1000001];inttt,n,m,num=0;Chars[ -],c[1000001];queue<int>Q;inlinevoid inch(){ intp=0, L; for(RegisterintI=0; i<m;i++) {L=s[i]-'a'; if(!t[p].t[l]) t[p].t[l]=++num; P=T[p].t[l]; } T[P].W++;} InlinevoidMafa () {RegisterintIintk,p; Q.push (0); t[0].f=0; while(!Q.empty ()) {k=Q.front (); Q.pop (); for(i=0;i< -; i++) if(T[k].t[i]) {p=t[k].f; while((!t[p].t[i]) &&p) p=t[p].f; T[T[K].T[I]].F= (k==p)?0: T[p].t[i]; //printf ("%d%d%d%d\n", I,k,p,t[t[k].t[i]].f,t[p].t[i]);Q.push (T[k].t[i]); }}}inlinevoidque () {registerinti,j; intans=0, K=strlen (c), p=0, X; for(i=0; i<k;i++) {x=c[i]-'a'; while(!t[p].t[x]&&p) p=t[p].f; //printf ("%d%d%d\n", I,p,ans);p=T[p].t[x]; if(T[P].W) for(J=P;J;J=T[J].F) ans+=t[j].w,t[j].w=0; } printf ("%d\n", ans);}intMain () {registerinti,j; scanf ("%d",&TT); while(tt--){ for(i=0; i<=num;i++) for(j=0; j<= -; j + +) T[i].t[j]=0; for(i=0; i<=num;i++) t[i].w=t[i].f=0; Num=0; scanf ("%d",&N); for(i=1; i<=n;i++) {scanf ("%s", s); M=strlen (s); inch(); } Mafa (); scanf ("%s", c); Que (); }}
Finally, I recommend several blog posts:
http://blog.csdn.net/niushuai666/article/details/7002823
Http://www.cnblogs.com/kuangbin/p/3164106.html
AC Automatic Machine