• 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 }
  • 相关阅读:
    从产品原型到交互设计的过渡——初学者心得
    谈什么是卡片式设计?
    vertical-align:middle的居中细节调整
    line-height:2和line-height:2em的区别,它们是有区别的
    css中!important的用法总结
    使用em为单位制作两列弹性布局
    如何动态修改下拉列表的默认选中项
    【转】深入浅出协议栈
    经典排序js实现
    js 数组的拷贝
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6440214.html
Copyright © 2020-2023  润新知