Link: http://zerojudge.tw/ShowProblem? Problemid = b179
First of all, you must have a thorough understanding of the AC automatic machine !!
A good question. In addition to the character string at the end of each day, the character at the beginning will disappear to make the length shorter. Finally, we need to count how many strings have disappeared in the n-day period, and how many strings have been hospitalized (including virus strings)
To describe this status, you need to consider the number of nodes with the length of the string after several days. Generally, this is the case with the DP of the automatic machine. The key is how to transfer the string.
First, expand a character at the end, which is the transfer of all the DP in the ordinary automatic machine.
However, it is nice to delete a character in the header.
In three cases
1: when the length of a string is 1, it disappears after deletion. In this case, the current status is added.
2: the length of the string is exactly the depth of the staying node. After the length is reduced by one, it cannot stay on the current node. Where can I go? Apparently the Fail pointer!
3: if the length of the string is greater than the depth of the node, the length must be reduced by one and stay on the current node.
It is invalid because the length is smaller than the depth of the current node.
Note that the first dimension should use a rolling array. Do not forget to clear the array when scrolling.
An error occurs once, but the array size is small.
A group of data for debugging
A
3
3
AB
CC
Dd
4 14
# Include <cstdio> # include <cstring> # include <map> # include <vector> # include <algorithm> using namespace STD; const int M = 1510; const int Cd = 4; int ID [128]; int ch [m] [cd]; int Q [m]; int fail [m]; int SZ; int Val [m]; void Init () {SZ = 1; memset (CH [0], 0, sizeof (CH [0]); fail [0] = 0; val [0] = 0; Id ['a'] = 0; Id ['B'] = 1; Id ['C'] = 2; id ['D'] = 3;} int Dep [m]; void insert (char * s) {int p = 0; int D = 0; For (; * s; s ++) {d ++; int c = ID [* s]; If (! Ch [p] [c]) {memset (CH [SZ], 0, sizeof (CH [SZ]); Val [SZ] = 0; dep [SZ] = D; ch [p] [c] = SZ ++;} p = CH [p] [c];} Val [p] = 1 ;} void construct () {int * s = Q, * E = Q; For (INT I = 0; I <CD; I ++) {If (CH [0] [I]) {fail [CH [0] [I] = 0; * E ++ = CH [0] [I];} while (s! = E) {int u = * s ++; For (INT I = 0; I <CD; I ++) {Int & V = CH [u] [I]; if (v) {* E ++ = V; fail [v] = CH [fail [u] [I]; val [v] | = Val [fail [v];} else {v = CH [fail [u] [I] ;}}} const int mod = 10007; char STR [110]; int DP [2] [110] [1510]; bool Init (char * s) {memset (DP, 0, sizeof (DP )); int p = 0, Len = 0; For (; * s; s ++) {Len ++; int c = ID [* s]; P = CH [p] [c];} DP [0] [Len] [p] = 1; if (Val [p]) return false; return true ;} void solve (int n) {bool flag = Init (Str ); If (! Flag) {puts ("0 1 \ n"); return;} int x = 0, ANS = 0, ret = 0; For (INT I = 0; I <N; I ++) {x ^ = 1; for (INT y = 1; y <= 100; y ++) memset (DP [x] [Y], 0, sizeof (DP [x] [Y]); For (Int J = 0; j <SZ; j ++) if (! Val [J]) {for (INT Len = 1; Len <= 100; Len ++) if (DP [x ^ 1] [Len] [J]) // the string length is Len staying on the J node {If (LEN = 1) {ans = (ANS + dp [x ^ 1] [Len] [J]) % MOD;} else if (LEN = Dep [J]) {DP [x] [len-1] [fail [J] + = DP [x ^ 1] [Len] [J]; DP [x] [len-1] [fail [J] % = MOD;} else if (LEN> Dep [J]) {DP [x] [len-1] [J] + = DP [x ^ 1] [Len] [J]; DP [x] [len-1] [J] % = MOD;} For (int K = 0; k <4; k ++) {int to = CH [J] [k]; DP [x] [Len + 1] [to] + = DP [x ^ 1] [Len] [J]; DP [x] [Len + 1] [to] % = MOD; If (Val [to]) {ret = (Ret + dp [x ^ 1] [Len] [J]) % mod ;}}} printf ("% d \ n", ANS, RET);} int main () {char s [110]; Init (); scanf ("% s", STR); int N, P; scanf ("% d", & N, & P); For (INT I = 0; I <p; I ++) {scanf ("% s ", s); insert (s);} construct (); solve (n); Return 0;}/* a33abccdd4 14 */