首页 > 代码库 > bzoj 1030: [JSOI2007]文本生成器

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 }

 

bzoj 1030: [JSOI2007]文本生成器