https://www.lydsy.com/JudgeOnline/problem.php?id=1030
求长度为m不包含n个子串的种数,
跑完ac自动机之后没办法跑矩阵快速幂,因为状态数比较大(6000),所以dp转移,dp[i][j]表示前i个跑到j状态的不包含子串的情况数
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define vi vector<int> //#define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pli pair<ll,int> #define pii pair<int,int> #define cd complex<double> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=6000+10,maxn=200000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; ll n,m,dp[110][N]; ll quick(ll a,ll b,ll c) { ll ans=1; while(b) { if(b&1)ans=ans*a%c; a=a*a%c; b>>=1; } return ans; } char s[N]; struct ACM{ int root,tot; int Next[N][30],fail[N],End[N]; int newnode() { memset(Next[tot],-1,sizeof Next[tot]); End[tot]=0; return tot++; } ACM() { tot=0; root=newnode(); } void ins() { int now=root,len=strlen(s); for(int i=0;i<len;i++) { if(Next[now][s[i]-'A']==-1) Next[now][s[i]-'A']=newnode(); now=Next[now][s[i]-'A']; } End[now]=1; } void build() { queue<int>q; fail[root]=root; for(int i=0;i<26;i++) { if(Next[root][i]==-1)Next[root][i]=root; else { fail[Next[root][i]]=root; q.push(Next[root][i]); } } while(!q.empty()) { int now=q.front(); q.pop(); if(End[fail[now]])End[now]=1; for(int i=0;i<26;i++) { if(Next[now][i]==-1)Next[now][i]=Next[fail[now]][i]; else { fail[Next[now][i]]=Next[fail[now]][i]; q.push(Next[now][i]); } } } } void solve() { dp[0][0]=1; for(int i=1;i<=m;i++) { for(int j=0;j<tot;j++) { if(!End[j]&&dp[i-1][j]) { for(int k=0;k<26;k++) { int now=j; while(Next[now][k]==-1)now=fail[now]; dp[i][Next[now][k]]=(dp[i][Next[now][k]]+dp[i-1][j])%10007; } } } } ll ans=quick(26,m,10007); for(int i=0;i<tot;i++) if(!End[i]) ans=((ans-dp[m][i])%10007+10007)%10007; printf("%lld ",ans); } }ac; int main() { scanf("%lld%lld",&n,&m); for(int i=0;i<n;i++) { scanf("%s",s); ac.ins(); } ac.build(); ac.solve(); return 0; } /*********************** ***********************/