• bzoj 1030: [JSOI2007]文本生成器


     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 char ch[105],s[106];
     6 int n,m,a[6007][27],size=1,fail[6007],dui[6007],b[101][6007],sum,sum1;
     7 bool f[6007];
     8 void jia()
     9 {
    10     int now=1,l=strlen(ch);
    11     for(int i=0;i<l;i++)
    12       {
    13         int t=ch[i]-'A'+1;
    14         if(a[now][t])
    15           now=a[now][t];
    16         else
    17           {
    18             size++;
    19             now=a[now][t]=size;
    20           }
    21       }
    22     f[now]=1;
    23 }
    24 void shi()
    25 {
    26     int t=1,h=0;
    27     dui[1]=1;
    28     for(;h<t;)
    29       {
    30         int k=dui[++h];
    31         for(int i=1;i<=26;i++)
    32           if(a[k][i])
    33             {
    34                 int x=fail[k];
    35                 for(;!a[x][i];x=fail[x]);
    36                 fail[a[k][i]]=a[x][i];
    37                 if(f[a[x][i]])
    38                   f[a[k][i]]=1;
    39                 dui[++t]=a[k][i];
    40               }
    41       }
    42 }
    43 void dp(int a1)
    44 {
    45     for(int i=1;i<=size;i++)
    46       {
    47         if(f[i]||!b[a1-1][i])
    48           continue;
    49         for(int j=1;j<=26;j++)
    50           {
    51             int k=i;
    52             for(;!a[k][j];k=fail[k]);
    53               b[a1][a[k][j]]=(b[a1][a[k][j]]+b[a1-1][i])%10007;
    54           }
    55       }
    56 }
    57 int main()
    58 {
    59     for(int i=1;i<=26;i++)
    60       a[0][i]=1;
    61     scanf("%d%d",&n,&m);
    62     for(int i=0;i<n;i++)
    63       {
    64         scanf("%s",ch);
    65         jia();
    66       }
    67     shi();
    68     b[0][1]=1;
    69     for(int i=1;i<=m;i++)
    70       dp(i);
    71     sum=1;
    72     for(int i=1;i<=m;i++)
    73       sum=(sum*26)%10007;
    74     for(int i=1;i<=size;i++)
    75       if(!f[i])
    76       sum1=(sum1+b[m][i])%10007;
    77     printf("%d
    ",(sum-sum1+10007)%10007);
    78     return 0;
    79 }

    AC自动机 将所有单词读入建出AC自动机,再在fail树上跑即可,用总可能数减去没有单词的数,没有单词的数用dp求,b[i][j]是第i个字符匹配到AC自动机上的j节点

  • 相关阅读:
    xhr
    原生js的博客
    webstorm调试Node的时候配置
    multiparty
    bluebird
    Nodejs+express+angularjs+mongodb
    mustache.js
    ModelProxy 前端接口配置建模框架
    浏览器跨域访问解决方案
    前端性能优化补充篇
  • 原文地址:https://www.cnblogs.com/xydddd/p/5229249.html
Copyright © 2020-2023  润新知