introduced
What is an AC automaton?
The first thing to know is that KMP,KMP is a single string match
Next you know the dictionary tree, which is used to store a bunch of strings
AC automata is that they combine: multi-string matching
Use a lot of people on the Internet to cite examples
Finding out the number of occurrences of certain strings in an article is the function of the AC automata built trie
Fo (i,1,m)
{
scanf ("%s", t+1);
scanf ("\ n");
int k=1;
Fo (J,1,strlen (t+1))
{
int l=t[j]-96;
if (c[k][l]==0) C[k][l]=++tot;
DEEP[C[K][L]]=DEEP[K]+1;K=C[K][L];
}
c[k][0]=1;//mark at the end of each string
}
fail
KMP has a next array
To the AC automaton, there is a fail array of the same function
Build fail thought oneself yy or find the national team paper, online A lot of information is not reliable
Build Fail Program
void Buildfail ()
{
int j=1,h=0;d[j]=1;
for (;h<j;)
{
int k=d[++h],p=0;
Fo (i,1,26)
if (c[k][i]!=0)
{
int p=c[k][i];
if (p)
{
int z=fail[k];
while (z!=0&&c[z][i]==0) z=fail[z];
Fail[p]=c[z][i];
d[++j]=p;
}
fail[p]= (fail[p]==0) 1:fail[p];
up[p]=p;}}}
With the queue, the C array is trie, and the second dimension is the 26-letter Query
Query is almost the same, for every time from the fail chain to walk
void query ()
{
int k=1;
Fo (i,1,n)
{
int j=s[i]-96;
while (k!=1 && c[k][j]==0) k=fail[k];
k=c[k][j];k= (k==0) 1:k;
while (p!=1)
{
if (c[p][0]==1) ans++;
P=FAIL[P];
If you can't repeat it, Mark C[p][0] as negative.}}
}
Set up the topic, flexible use, plus a variety of optimization. Template title: Tile Description
A town's main street is composed of n lowercase letters, the mayor is ready to tile on top, the ceramic tile a total of M, the first class I have Li small letter, tile can not be rotated can not be separated, tile can only be affixed to its body letter exactly the same place, allow tile overlap, and the number of the same tile is infinite.
Ask the street how many letters (places) cannot be covered by tiles. Input
The first line enters street length N (1<=n<=300,000).
In the second line, enter n English lowercase letters to describe the street situation.
The third line is input M (1<=m<=5000), which indicates the type of tile.
Next m line, each line describes a tile, the length of Li (1<=li<=5000), all composed of lowercase letters. Output
How many places the output cannot be covered by a tile. Sample Input
Input 1:
6
Abcbab
2
Cb
Cbab
Input 2:
4
Abab
2
Bac
Baba
Input 3:
6
Abcabc
2
Abca
Cab Sample Output
Output 1:
2
Output 2:
4
Output 3:
1 Data Constraint
N (1<=n<=300,000) The problem is the bare topic of AC automata
Add a small optimization: use Up[x] to represent the x along the fail chain of the first value point, so that the loop is not used
to find the answer on the line segment ~ ~ Code
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define FO (i,a,b) for
(int i=a;i<=b;i++) #define N 301000 #define M 5010 using namespace std;
Char S[n],t[m];
int n,m,fail[m*1000],deep[m*1000],c[m*800][28],ans[n][2],bz[n],up[m*1000],tot=1,d[m*1000];
void Buildfail () {int j=1,h=0;d[j]=1;
for (;h<j;)
{int k=d[++h],p=0;
FO (i,1,26) if (c[k][i]!=0) {int p=c[k][i];
if (p) {int z=fail[k];
while (z!=0&&c[z][i]==0) z=fail[z];
Fail[p]=c[z][i];
D[++j]=p;
} fail[p]= (fail[p]==0) 1:fail[p];
Up[p]=p;
if (c[up[p]][0]==0&&up[p]!=1) up[p]=up[fail[p]];//up}}} void query () {int k=1;
Fo (i,1,n) {int j=s[i]-96;
while (k!=1 && c[k][j]==0) k=fail[k];
k=c[k][j];k= (k==0) 1:k; ANS[++ANS[0][0]][0]=i;ans[ans[0][0]][1]=deep[up[k]];
Because the topic is special, the answer can also be a special point}} int main () {freopen ("acauto.in", "R", stdin);
scanf ("%d\n", &n);
scanf ("%s", s+1);
scanf ("%d\n", &m);
Fo (i,1,m) {scanf ("%s", t+1);
scanf ("\ n");
int k=1;
Fo (J,1,strlen (t+1)) {int l=t[j]-96;
if (c[k][l]==0) C[k][l]=++tot;
DEEP[C[K][L]]=DEEP[K]+1;K=C[K][L];
} c[k][0]=1;
} buildfail ();
Query ();
Fo (i,1,ans[0][0]) {bz[ans[i][0]+1]--;bz[ans[i][0]-ans[i][1]+1]++;
} int an=0,jy=0;
Fo (i,1,n) {jy+=bz[i];if (jy==0) an++;
} printf ("%d", an); }