zoukankan      html  css  js  c++  java
  • 【BZOJ1030】[JSOI2007]文本生成器

    【题意】

        给定一些单词,我们定义一篇可读文章至少包含一个这样的单词,求长度为M的可读文章总数。

    【分析】

       用前几题的方法可以求长度为M的不可读的文章总数Sum,所以我们可以用26^M-Sum来求出可读文章的总数。不过这题的N*Len太大,也就是AC自动机的节点太多,如果用矩阵乘法求解用爆空间,所以我直接DP了。

    代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4  
      5 const int Maxn=80;
      6 const int Maxl=110;
      7 const int Mod=10007;
      8  
      9 int n,m,tot,len,total;
     10 int q[Maxl*Maxn],f[Maxl][Maxl*Maxn];
     11 char s[Maxl];
     12  
     13 struct node
     14 {
     15     int son[27],fail;
     16     bool mark;
     17 }t[Maxn*Maxl];
     18  
     19 void floy()
     20 {
     21     tot=0,total=0;
     22     memset(f,0,sizeof(f));
     23     memset(q,0,sizeof(q));
     24     for(int i=1;i<=Maxl*Maxn;i++)
     25     {
     26         t[i].mark=0;
     27         for(int j=1;j<=26;j++) t[i].son[j]=0;    
     28     }
     29 }
     30  
     31 void read_trie()
     32 {
     33     tot=0;
     34     int i,j;
     35     scanf("%d%d",&n,&m);
     36     for(i=1;i<=n;i++)
     37     {
     38         int x,ind;
     39         scanf("%s",s+1);
     40         len=strlen(s+1);
     41         x=0;
     42         for(j=1;j<=len;j++)
     43         {
     44             ind=s[j]-'A'+1;
     45             if(!t[x].son[ind]) t[x].son[ind]=++tot;
     46             x=t[x].son[ind];
     47             if(j==len) t[x].mark=1;
     48         }
     49     }
     50 }
     51  
     52 void build_AC()
     53 {
     54     int i,j,x,y;
     55     q[++q[0]]=0;
     56     for(i=1;i<=q[0];i++)
     57     {
     58         x=q[i];y=t[x].fail;
     59         for(j=1;j<=26;j++)
     60         {
     61             if(t[x].son[j])
     62             {
     63                 t[t[x].son[j]].fail=x?t[y].son[j]:0;
     64                 if(t[t[t[x].son[j]].fail].mark) t[t[x].son[j]].mark=1;
     65                 q[++q[0]]=t[x].son[j];
     66             }
     67             else t[x].son[j]=t[y].son[j];
     68         }
     69     }
     70 }
     71  
     72 void dp()
     73 {
     74     int i,j,k,v;
     75     f[0][0]=1;
     76     for(i=1;i<=m;i++)
     77      for(j=0;j<=tot;j++) if(f[i-1][j])
     78          for(k=1;k<=26;k++)
     79          {
     80             v=t[j].son[k];
     81             if(!t[v].mark) f[i][v]=(f[i][v]+f[i-1][j])%Mod;
     82         }
     83     for(i=0;i<=tot;i++)
     84      total=(total+f[m][i])%Mod;
     85 }
     86  
     87 int pow(int x)
     88 {
     89     int ans=26,sum=1;
     90     while(x)
     91     {
     92         if(x&1) sum=(sum*ans)%Mod;
     93         ans=(ans*ans)%Mod;
     94         x=x>>1;
     95     }
     96     return sum;
     97 }
     98  
     99 int main()
    100 {
    101     read_trie();
    102     build_AC();
    103     dp();
    104     printf("%d
    ",(pow(m)-total+Mod)%Mod);
    105 }
    [BZOJ1030]

    2016-07-12 10:10:32

  • 相关阅读:
    Codeforces F. Bits And Pieces(位运算)
    一场comet常规赛的台前幕后
    【NOIP2019模拟2019.9.4】B(期望的线性性)
    「NOI2016」循环之美(小性质+min_25筛)
    【NOI2011】兔农(循环节)
    LOJ #6538. 烷基计数 加强版 加强版(生成函数,burnside引理,多项式牛顿迭代)
    noi2019感想
    7.12模拟T2(套路容斥+多项式求逆)
    CF 848E(动态规划+分治NTT)
    CF 398 E(动态规划)
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5662545.html
Copyright © 2011-2022 走看看