Title: https://www.lydsy.com/JudgeOnline/problem.php?id=1030
The text string of at least one word is not very good, so it is converted into a text string that asks for all cases minus a single word;
A text string without a word can be +dp by an AC automaton, and a f[i][j] means the length of the text string is I, and the number of the nodes on the current Trie tree is J;
Then F[i][j] can go to the scheme number of its son that still does not contain the word, while the length of the text string is +1;
So you need to getfail the end of the attribute also transferred, because fail is the end of the word, you must have a suffix is the end of the word, that is, they also contain words;
The final statistic answer is all F[m][i] and, where I can be any point on the Trie tree.
The code is as follows:
#include <iostream>#include<cstdio>#include<cstring>#include<queue>using namespacestd;int ConstMod=10007;intn,m,f[ the][6005],cnt,ans;Chars[ the];queue<int>Q;structn{intson[ -],fail,end;} t[6005];voidbuild () {intL=strlen (s), nw=0; for(intI=0; i<l;i++) { if(!t[nw].son[s[i]-'A']) t[nw].son[s[i]-'A']=++CNT; NW=t[nw].son[s[i]-'A']; } t[nw].end=1;}voidGetfail () {t[0].fail=0; for(intI=0;i< -; i++) if(t[0].son[i]) {t[t[0].son[i]].fail=0; Q.push (t[0].son[i]); } while(Q.size ()) {intx=Q.front (); Q.pop (); for(intI=0;i< -; i++) { if(T[x].son[i]) {T[t[x].son[i]].fail=T[t[x].fail].son[i];//T[t[x].son[i]].end|=t[t[t[x].son[i]].fail].end;Q.push (T[x].son[i]); } Elset[x].son[i]=T[t[x].fail].son[i]; } if(t[t[x].fail].end) t[x].end=1; } }intMain () {scanf ("%d%d",&n,&m); for(intI=1; i<=n;i++) {cin>>R; Build (); } getfail (); f[0][0]=1;//! for(intI=0; i<m;i++) for(intnw=0; nw<=cnt;nw++) { if(t[nw].end| |! F[I][NW])Continue;// for(intj=0;j< -; j + +) { intx=T[nw].son[j]; (F[i+1][X]+=F[I][NW])%=MoD; }} ans=1; for(intI=1; i<=m;i++) (ans*= -)%=MoD; for(intI=0; i<=cnt;i++) if(t[i].end==0) ans= ((Ans-f[m][i])%mod+mod)%mod;//end=0!printf"%d", ans); return 0;}
bzoj1030 [JSOI2007] Text generator--ac automaton +DP