比较容易看出来先建立ac自动机,然后在自动机上做DP,设w[0..1][i][j]为当前不包括/包括字典中的字符串,当前在自动机中走到第i个节点,完成的文本的长度为j的方案数,那么比较容易的转移w[i|j->child->cnt][j->child][k+1]+=w[i][j][k]。

  

/**************************************************************
    Problem: 1030
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:200 ms
    Memory:25596 kb
****************************************************************/
 
//By BLADEVIL
#include <cstdio>
#include <cstring>
#define maxn 10010
#define maxm 200
#define d39 10007
 
using namespace std;
 
int n,m;
int w[][maxm][maxn];
 
struct node{
    int cnt,num;
    node *child[],*fail;
    node (){
        cnt=num=;
        memset(child,,sizeof child);
        fail=NULL;
    }
} nodepool[maxn],*totnode,*root,*que[maxn];
 
void build_trie(){
    totnode=nodepool; root=totnode++;
    for (int i=;i<=n;i++){
        char c[maxm];
        scanf("%s",&c);
        int len=strlen(c);
        node *t=root;
        for (int j=;j<len;j++){
            if (!t->child[c[j]-'A']) t->child[c[j]-'A']=totnode++;
            t=t->child[c[j]-'A'];
        }
        t->cnt=;
    }
}
 
void build_ac(){
    int h=,t=;
    que[]=root; root->fail=root;
    for (int i=;i<;i++) if (!root->child[i])   root->child[i]=root;
    while (h<t){
        node *u=que[++h];
        for (int i=;i<;i++) if (u->child[i]&&u->child[i]!=root){
            que[++t]=u->child[i];
            que[t]->fail=u->fail->child[i]!=que[t]?u->fail->child[i]:root;
            que[t]->cnt|=que[t]->fail->cnt;
        } else u->child[i]=u->fail->child[i];
    }
}
 
void dp(){
    int j=;
    for (node *i=nodepool;i!=totnode;i++) i->num=j++;
//for (node *i=nodepool;i!=totnode;i++) printf("%d %d %d\n",i->cnt,i->num,i->fail->num);
    w[][][]=;
    for (int t=;t<;t++)
        for (int i=;i<=m;i++)
            for (node *j=nodepool;j!=totnode;j++)
                if (w[t][i][j->num])
                    for (int k=;k<;k++)
                        (w[t|j->child[k]->cnt][i+][j->child[k]->num]+=w[t][i][j->num])%=d39;
    int ans=;
    for (node *i=nodepool;i!=totnode;i++)
        (ans+=w[][m+][i->num])%=d39;
    printf("%d\n",ans);
}
 
int main(){
    scanf("%d%d",&n,&m);
    build_trie();
    build_ac();
    dp();
    return ;
}

  

bzoj 1030 ac自动机的更多相关文章

  1. bzoj 1030 AC自动机+dp

    代码: //先把给的单词建AC自动机并且转移fail,然后d[i][j]表示构造的文章到第i位时处在字典树的第j个节点的不包含单词的数量,最后用总的数量26^m //-d[m][0~sz]即可.其中不 ...

  2. bzoj 3172 AC自动机

    初学AC自动机,要先对于每一个模式串求出来trie树,在此基础上构建fail指针,然后在trie树加上失配边构建出整张trie图. AC自动机的原理和KMP差不多,一个节点的fail指针就是指向tri ...

  3. 【无聊放个模板系列】BZOJ 3172 (AC自动机)

    #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #inc ...

  4. bzoj 2434 AC自动机+树状数组

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3493  Solved: 1909[Submit][Sta ...

  5. bzoj 2434 ac自动机

    ac自动机中,如果以trie中的节点为节点,(fail[i],i)为边,可以建立一颗树,该树有如下特点:“节点u是节点v的祖先 当且仅当 u代表的字符串是v代表的字符串的一个后缀”.(u代表的字符串是 ...

  6. bzoj 2754 ac自动机

    第一道AC自动机题目. 记一下对AC自动机的理解吧: AC自动机=Trie+KMP.即在Trie上应用KMP思想,实现多Pattern的匹配问题. 复杂度是预处理O(segma len(P)),匹配是 ...

  7. bzoj 2434 AC自动机 + fail指针建树 + 树状数组

    思路:我们先跟着它给定的字符串走把字典树建出来,求出fail指针,我们考虑两个字符串 A和B, 如果想要求B中有多少A的子串,转换一下就是有多少个B的前缀的后缀包含A,这个在AC自动机 的状态图中很容 ...

  8. bzoj 1444 AC自动机 + 矩阵乘法 | 高斯消元

    恶补了一下AC自动机,花了一天时间终于全部搞明白了. 思路:将每个人的串加入AC自动机,在AC自动机生成的状态图上建边,注意单词末尾的节点只能转移到自己概率为1, 然后将矩阵自乘几十次后误差就很小了, ...

  9. BZOJ 3940 AC自动机

    思路: 需要维护一个栈的AC自动机--. 要求出来 最后的栈顶是在自动机上的哪个节点. if(!ac.ch[st[tp-1]][a[i]-'a']) st[tp]=ac.ch[ac.f[st[tp-1 ...

随机推荐

  1. SpringData——HelloWorld

    1.背景 最开始了解SpringData的时候,以为他不就是ORM的一种实现方式嘛,还能有什么新的东西.从hibernate到ibatis.mybatis,也许他只不过是spring想整合一个更方便的 ...

  2. IIS发布 MVC 配置

    E:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll

  3. File文件以及.propertites文件操作

    File文件操作 在jsp和class文件中调用的相对路径不同.在jsp里,根目录是WebRoot 在class文件中,根目录是WebRoot/WEB-INF/classes 当然你也可以用Syste ...

  4. Spring Boot中使用@Transactional注解配置事务管理

    事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持.Spring 事务管理分为编程式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP ...

  5. c#调用系统默认软件打开应用

    System.Diagnostics.Process.Start(),参数为对应的应用路径 System.Diagnostics.Process.Start(((FileInfo)lv.Selecte ...

  6. 【转载】用C#编写一个简单的记事本

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  7. [NOIP2016 TG D2T3]愤怒的小鸟

    题目大意:有一架弹弓位于(0,0)处,每次可以用它向第一象限发射一只小鸟,飞行轨迹均为形如y=ax2+bxy=ax+bx2 y=ax2+bx的曲线,且必须满足a<0(即是下开口的) 平面的第一象 ...

  8. Android 自定义View消除锯齿实现图片旋转,添加边框及文字说明

    先看看图片的效果,左边是原图,右边是旋转之后的图:   之所以把这个写出来是因为在一个项目中需要用到这样的效果,我试过用FrameLayout布局如上的画面,然后旋转FrameLayout,随之而来也 ...

  9. POJ1743:Musical Theme——题解

    http://poj.org/problem?id=1743 给一段数,求最大相似子串长度,如果没有输出0. 相似子串定义: 1.两个不重叠的子串,其中一个是另一个加/减一个数得来的. 2.长度> ...

  10. BZOJ1502:[NOI2005]月下柠檬树——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1502 https://www.luogu.org/problemnew/show/P4207 李哲 ...