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

      AC自动机入门题。。。。

      然而我只想入门以防KOI出题人送分(其实是智商硬伤)。。。YY一下感觉AC自动机还很正常然而写起来就各种跪

      显然是用总的串数减去不可读的串数。。。而不可读串数就是AC自动机上走m步(从根出发),并且不经过任何一个完整的可识别单词的路径数。

      “不经过任何一个完整的可识别单词”就是说走的每个节点都不是结束节点,并且fail指针指向的也不是结束节点。(这就保证从根到这个节点上的路径不包含完整的单词)

      把AC自动机建出来,然后在上面dp

      f[i][j]表示走了i步,最后在自动机的j号节点上的路径数。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 using namespace std;
     6 const int sxt=10007;const int maxn=66;const int maxlen=103;
     7 
     8 int fail[maxn*maxlen],ch[maxn*maxlen][26],dl[maxn*maxlen],tot,len,l,r;
     9 bool tag[maxn*maxlen];//是结尾节点,或者fail指向结尾节点 
    10 char s[maxlen];
    11 
    12 int f[2][maxn*maxlen],pre,now;
    13 int i,j,k,n,m,ans;
    14 
    15 inline void insert(int len){
    16     register int i,now;
    17     for(i=1;i<=len;i++)s[i]-='A';
    18     for(now=0,i=1;i<=len;i++)
    19         now=ch[now][s[i]]?ch[now][s[i]]:ch[now][s[i]]=++tot;
    20     tag[now]=1;
    21 }
    22 inline void getfail(){
    23     register int i,j,tmp;
    24     l=0,r=1,dl[1]=0;
    25     while(l<r)
    26         for(j=0,i=dl[++l];j<26;j++)if(ch[i][j]){
    27             for(tmp=fail[i];tmp&&!ch[tmp][j];tmp=fail[tmp]);
    28             fail[ch[i][j]]=i?ch[tmp][j]:0,
    29             tag[ch[i][j]]|=tag[ch[tmp][j]];
    30             dl[++r]=ch[i][j];
    31         }    
    32 }
    33 
    34 int main(){
    35     register int j,k,tmp;
    36     scanf("%d%d",&n,&m);
    37     for(i=ans=1;i<=m;i++){
    38         ans*=26;if(ans>=sxt)ans%=sxt;
    39     }
    40     for(i=1;i<=n;i++){
    41         for(s[len=1]=getchar();s[1]<'A'||s[1]>'Z';s[1]=getchar());
    42         while(s[len]>='A'&&s[len]<='Z')s[++len]=getchar();
    43         len--,insert(len);
    44     }
    45     getfail();
    46     f[0][0]=1;
    47     for(i=1,now=1,pre=0;i<=m;i++,swap(now,pre))
    48         for(memset(f[now],0,(tot+1)<<2),j=dl[l=1];l<=r;j=dl[++l])if(!tag[j]&&f[pre][j])
    49         for(k=0;k<26;k++){
    50             for(tmp=j;tmp&&!ch[tmp][k];tmp=fail[tmp]);
    51             tmp=ch[tmp][k];
    52             if(!tag[tmp])
    53             f[now][tmp]+=f[pre][j],f[now][tmp]-=f[now][tmp]>=sxt?sxt:0;
    54         }
    55     for(i=0;i<=tot;i++)
    56         ans-=f[pre][i],ans+=ans<0?sxt:0;
    57     printf("%d
    ",ans);
    58     return 0;
    59 }
    View Code

    代码跑得奇慢而且毫无可读性QAQ

  • 相关阅读:
    LNMP架构三
    LNMP架构二
    LNMP架构
    LAMP架构三
    LAMP架构二
    LAMP架构
    rsync工具介绍
    mysqldump备份单表数据
    阿铭每日一题 day 14 20180125
    阿铭每日一题 day 13 20180124
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5185964.html
Copyright © 2011-2022 走看看