Very old topic, a long time ago to learn AC automata when the A once
It's a review today.
We can turn the problem into a string that does not appear in a given string.
We set up AC automata, set DP[I][J] to show that I have walked the current on the J-node
The word node is not transferred during DP
#include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include < Algorithm> #include <queue>using namespace std;const int Maxn=6010;const int Mod=10007;int N,m,cnt=1,ans;char s [Maxn];int t[maxn][26];int fail[maxn];int dp[102][maxn];bool end[maxn];queue<int>q;void Insert () {scanf ("%s", s +1); int Len=strlen (s+1), now=1;for (int i=1;i<=len;++i) {int id=s[i]-' A '; if (!t[now][id]) t[now][id]=++cnt;now=t[ Now][id];} End[now]=true;} void Build_fail () {Q.push (1); Fail[1]=0;while (! Q.empty ()) {int U=q.front (); Q.pop (); end[u]|=end[fail[u]];for (int i=0;i<26;++i) {int k=fail[u];while (k&&!t[k][i]) k=fail[k];if (t[u][ I]) {fail[t[u][i]]=k?t[k][i]:1; Q.push (T[u][i]);} else t[u][i]=k?t[k][i]:1;}} return;} void Get_dp () {dp[0][1]=1;for (int i=0;i<m;++i) {for (int j=1;j<=cnt;++j) {if (!dp[i][j]) continue;for (int k=0;k <26;++K) {int now=t[j][k];if (End[now]) continue;dp[i+1][now]+=dp[i][j];if (dp[i+1][now]>=mod) dp[i+1][now]-= mod;}}} return;} int pow_mod (int v,int p) {int Tmp=1;while (p) {if (p&1) tmp=tmp*v%mod;v=v*v%mod;p>>=1;} return TMP;} int main () {scanf ("%d%d", &n,&m), for (int i=1;i<=n;++i) insert (); Build_fail (); GET_DP (); ans=0;for (int i=1;i<=cnt;++i) {ans=ans+dp[m][i];if (ans>=mod) Ans-=mod;} Ans=pow_mod (26,m)-ans;ans= (ans+mod)%mod;printf ("%d\n", ans); return 0;}
Bzoj 1030 Text Generator