P3808 [TEMPLATE] AC automatic machine (simple edition) and p3808 Automatic Machine
Background
This is a simple template question for AC automatic machines.
Used to detect correctness and algorithm constants.
To prevent the card OJ, only two groups of data are supported based on the guarantee. do not submit the data maliciously.
Description
Given n mode strings and one text string, the number of mode strings has exists in the text string.
Input/Output Format
Input Format:
The first line contains n, indicating the number of mode strings;
Each row of n Rows has one mode string;
The following line contains a text string.
Output Format:
One number indicates the answer
Input and Output sample input sample #1:
2aaaaa
Output sample #1:
2
Description
Subtask1 [50pts]: Σ length (mode string) <= 10 ^ 6, length (text string) <= 10 ^ 6, n = 1;
Subtask2 [50pts]: Σ length (mode string) <= 10 ^ 6, length (text string) <= 10 ^ 6;
It's also a template. There's nothing to say,
It's just that every update is ++, not = 1!
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <cmath> 5 # include <queue> 6 # include <algorithm> 7 # include <map> 8 using namespace std; 9 const int MAXN = 1000001; 10 void read (int & n) 11 {12 char c = '+'; int x = 0; bool flag = 0; 13 while (c <'0' | c> '9') {c = getchar (); if (c = '-') flag = 1 ;} 14 while (c> = '0' & c <= '9') {x = x * 10 + c-48; c = getchar ();} 15 flag = 1? N =-x: n = x; 16} 17 char s [MAXN]; 18 char text [MAXN]; 19 int n; 20 int ans = 0; 21 struct AC_Automata 22 {23 int sz; 24 int ch [MAXN] [26]; // trie tree 25 int val [MAXN]; // record whether the word 26 int last [MAXN]; 27 int f [MAXN]; 28 int sigma_sz; 29 void Init () 30 {31 memset (ch [0], 0, sizeof (ch [0]); 32 sz = 1; 33 sigma_sz = 26; 34} 35 int idx (char c) 36 {37 return c-'A '; 38} 39 void Insert (char * s, int pos) 40 {41 int l = str Len (s); int now = 0; 42 for (int I = 0; I <l; I ++) 43 {44 int c = idx (s [I]); 45 if (! Ch [now] [c]) 46 {47 memset (ch [sz], 0, sizeof (ch [sz]); 48 val [sz] = 0; 49 ch [now] [c] = sz ++; 50} 51 now = ch [now] [c]; 52} 53 val [now] ++; // end of a word 54} 55 void getfail () 56 {57 f [0] = 0; 58 queue <int> q; 59 for (int I = 0; I <sigma_sz; I ++) 60 {61 int u = ch [0] [I]; 62 if (u) // The word 63 {64 f [u] = 0 appears here; // connect to the root node 65 q. push (u); 66 last [u] = 0; // The previous word must be the root node 67 // the above two statements are useless, just to help understand the meaning of the AC automatic machine 68} 69} 70 while (! Q. empty () 71 {72 int p = q. front (); q. pop (); 73 for (int I = 0; I <sigma_sz; I ++) 74 {75 int u = ch [p] [I]; 76 if (! U) // No children 77 {78 ch [p] [I] = ch [f [p] [I]; // Add a nonexistent edge, reduce the number of searches 79 continue; 80} 81 q. push (u); 82 int v = f [p]; // find its out-of-box pointer 83 f [u] = ch [v] [I]; // because we add a non-existent edge on it, it must have the child 84 last [u] = val [f [u]? F [u]: last [f [u]; 85 // determines whether the end of the word is, not 86} 87} 88} 89 int OK (int pos) 90 {91 if (val [pos]) 92 {93 ans + = val [pos]; 94 val [pos] = 0; 95 OK (last [pos]); 96} 97} 98 void find (char * s) // query mode string 99 {100 int l = strlen (s); 101 int j = 0; // ID of the current node 102 for (int I = 0; I <l; I ++) 103 {104 int c = idx (s [I]); 105 while (j &&! Ch [j] [c]) 106 j = f [j]; // walk along the mismatched side 107 j = ch [j] [c]; // obtain the son 108 if (val [j]) 109 OK (j); // find the word 110 else if (last [j]) 111 OK (last [j]); // if the current node does not work, check that the row where the previous word appears is not 112} 113} 114} ac; 115 int main () 116 {117 scanf ("% d", & n); 118 ac. init (); 119 for (int I = 1; I <= n; I ++) 120 {121 scanf ("% s", s); 122 ac. insert (s, I); 123} 124 ac. getfail (); 125 scanf ("% s", text); 126 ac. find (text); 127 printf ("% d \ n", ans); 128 return 0; 129}