• 【BZOJ】【1030】【JSOI2007】文本生成器


    AC自动机/DP


      Orz ZYF

      玛雅快要省选了,赶紧复(xue)习(xi)一下AC自动机……

      其实在AC自动机上DP并没有当初想的那么复杂……就是把DP的转移关系换成了AC自动机上的边而已(不过这题好像搞成了Trie图?)

     1 /**************************************************************
     2     Problem: 1030
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:208 ms
     7     Memory:7148 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 1030
    11 #include<vector>
    12 #include<cstdio>
    13 #include<cstring>
    14 #include<cstdlib>
    15 #include<iostream>
    16 #include<algorithm>
    17 #define rep(i,n) for(int i=0;i<n;++i)
    18 #define F(i,j,n) for(int i=j;i<=n;++i)
    19 #define D(i,j,n) for(int i=j;i>=n;--i)
    20 #define pb push_back
    21 using namespace std;
    22 inline int getint(){
    23     int v=0,sign=1; char ch=getchar();
    24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    26     return v*sign;
    27 }
    28 const int N=6010,INF=~0u>>2;
    29 typedef long long LL;
    30 /******************tamplate*********************/
    31 const int MOD=10007;
    32 int n,m,cnt=1;
    33 struct Trie{
    34     int ch[26],cnt,fail;
    35     bool sign;
    36 }T[N];
    37 inline int id(char c){return c-'A';}
    38 void ins(char *s){
    39     int x=1,y;
    40     rep(i,strlen(s)){
    41         y=id(s[i]);
    42         if (T[x].ch[y]==0)
    43             T[x].ch[y]=++cnt;
    44         x=T[x].ch[y];
    45     }
    46     T[x].sign=1;
    47 }
    48 int Q[N];
    49 void make_fail(){
    50     int l=0,r=-1;
    51     Q[++r]=1;
    52     while(l<=r){
    53         int x=Q[l++],y,j;
    54         rep(i,26){
    55             j=T[x].fail;
    56             while(j && !T[j].ch[i]) j=T[j].fail;
    57             if (T[x].ch[i]){
    58                 y=T[x].ch[i];
    59                 T[y].fail=j ? T[j].ch[i] : 1;
    60                 T[y].sign=T[y].sign|T[T[y].fail].sign;
    61                 Q[++r]=y;
    62             }else T[x].ch[i]=j ? T[j].ch[i] : 1;
    63         }
    64     }
    65 }
    66 int f[110][N][2];
    67 void dp(){
    68     f[0][1][0]=1;
    69     rep(i,m) F(j,1,cnt) rep(k,26) F(l,0,1)
    70         if(T[T[j].ch[k]].sign) 
    71             (f[i+1][T[j].ch[k]][1]+=f[i][j][l])%=MOD;
    72         else (f[i+1][T[j].ch[k]][l]+=f[i][j][l])%=MOD;
    73 }
    74 char s[N];
    75 int main(){
    76 #ifndef ONLINE_JUDGE
    77     freopen("1030.in","r",stdin);
    78     freopen("1030.out","w",stdout);
    79 #endif
    80     n=getint(); m=getint();
    81     F(i,1,n){
    82         scanf("%s",s);
    83         ins(s);
    84     }
    85     make_fail();
    86     dp();
    87     int ans=0;
    88     F(i,1,cnt) (ans+=f[m][i][1])%=MOD;
    89     printf("%d
    ",ans);
    90     return 0;
    91 }
    View Code

    1030: [JSOI2007]文本生成器

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 2224  Solved: 923
    [Submit][Status][Discuss]

    Description

    JSOI 交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版。该软件可以随 机生成一些文章―――总是生成一篇长度固定且完全随机的文章—— 也就是说,生成的文章中每个字节都是完全随机的。如果一篇文章中至少包含使用者们了解的一个单词,那么我们说这篇文章是可读的(我们称文章a包含单词b, 当且仅当单词b是文章a的子串)。但是,即使按照这样的标准,使用者现在使用的GW文本生成器v6版所生成的文章也是几乎完全不可读的。 ZYX需要指出GW文本生成器 v6生成的所有文本中可读文本的数量,以便能够成功获得v7更新版。你能帮助他吗?

    Input

    输入文件的第一行包含两个正整数,分别是使用者了解的单词总数N (<= 60),GW文本生成器 v6生成的文本固定长度M;以下N行,每一行包含一个使用者了解的单词。 这里所有单词及文本的长度不会超过100,并且只可能包含英文大写字母A..Z  。

    Output

    一个整数,表示可能的文章总数。只需要知道结果模10007的值。

    Sample Input

    2 2
    A
    B

    Sample Output

    100

    HINT

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    从 i++ 和 ++i 说起局部变量表和操作数栈
    数据库连接情况查询相关sql语句
    db2相关语句
    BeanUtils源码详解
    Spring注解驱动开发之AOP
    Spring注解驱动开发之IOC
    正则表达式
    linux特殊符号
    linux下面如何让一个软件/命令开机自启动
    linux文件属性
  • 原文地址:https://www.cnblogs.com/Tunix/p/4394952.html
Copyright © 2020-2023  润新知