bzoj 1030: [JSOI2007]文本生成器
AC自动机的fail,然后用fail搞搞DP,不懂不懂,,,,啊啊啊啊啊啊
1 #include<bits/stdc++.h> 2 #define N 1000005 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 const int mod=10007; 14 int n,m,sz=1,ans1,ans2=1; 15 int a[6001][27],fail[6001],q[6001],f[101][6001]; 16 char s[101]; 17 bool danger[6001]; 18 void ins() 19 { 20 int L=strlen(s),now=1; 21 for (int i=0; i<L; i++) 22 { 23 int t=s[i]-'A'+1; 24 if (a[now][t]) now=a[now][t]; 25 else now=a[now][t]=++sz; 26 } 27 danger[now]=1; 28 } 29 void ACmatch() 30 { 31 int l=0,r=1; q[0]=1; fail[1]=0; 32 while (l<r) 33 { 34 int x=q[l++]; 35 for (int i=1; i<=26; i++) 36 { 37 if (!a[x][i]) continue; 38 int k=fail[x]; 39 while (!a[k][i]) k=fail[k]; 40 fail[a[x][i]]=a[k][i]; 41 if (danger[a[k][i]]) danger[a[x][i]]=1; 42 q[r++]=a[x][i]; 43 } 44 } 45 } 46 void dp(int x) 47 { 48 for (int i=1; i<=sz; i++) 49 { 50 if (danger[i] || !f[x-1][i]) continue; 51 for (int j=1; j<=26; j++) 52 { 53 int k=i; 54 while (!a[k][j]) k=fail[k]; 55 f[x][a[k][j]]=(f[x][a[k][j]]+f[x-1][i])%mod; 56 } 57 } 58 } 59 int main() 60 { 61 n=ra(); m=ra(); 62 for (int i=1; i<=26; i++) a[0][i]=1; 63 for (int i=1; i<=n; i++) 64 scanf("%s",s),ins(); 65 ACmatch(); f[0][1]=1; 66 for (int i=1; i<=m; i++) dp(i); 67 for (int i=1; i<=m; i++) ans2=ans2*26%mod; 68 for (int i=1; i<=sz; i++) 69 if (!danger[i]) ans1=(ans1+f[m][i])%mod; 70 printf("%d",(ans2-ans1+mod)%mod); 71 return 0; 72 }