比较容易看出来先建立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. BAT批处理(五)

    批处理程序 一.交互界面设计 没啥说的,看看设计的菜单界面吧:@echo offclstitle 终极多功能修复:menuclscolor 0Aecho.echo ================== ...

  2. union查询

     select id, uid, money, FROM_UNIXTIME(created) as created, type FROM  (  #type=1是  cjw_finance_bonus ...

  3. 【Docker 命令】- ps命令

    docker ps : 列出容器 语法 docker ps [OPTIONS] OPTIONS说明: -a:显示所有的容器,包括未运行的. -f:根据条件过滤显示的内容. --format :指定返回 ...

  4. 使用js 复制 文字到剪贴板

    有一个好插件 https://clipboardjs.com/ 兼容性  IE9+ 一般基本够用,但如果非要兼容IE8 可使用IE 特有的 方法 window.clipboardData.setDat ...

  5. 第71天:jQuery基本选择器(二)

    jQuery选择器 一.内容过滤选择器 选择器 描 述 返 回 示 例 :contains(text) 匹配含有文本内容text的元素 集合元素 $(“p:contains(今天)”) :empty ...

  6. intelliJ IDEA最常用的快捷键

    一.使用相关快捷键 1.重写接口实现类:Ctrl+I 2.搜索:Shift+Shift   3.生成get或set方法快捷键:Alt+insert: 4.导入未实现的方法,强制类型转换:Alt+Ent ...

  7. 【刷题】BZOJ 4503 两个串

    Description 兔子们在玩两个串的游戏.给定两个字符串S和T,兔子们想知道T在S中出现了几次, 分别在哪些位置出现.注意T中可能有"?"字符,这个字符可以匹配任何字符. I ...

  8. BZOJ5289 & 洛谷4437:[HNOI/AHOI2018]排列——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5289 https://www.luogu.org/problemnew/show/P4437 考虑 ...

  9. BZOJ2654 & 洛谷2619:tree——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2654 https://www.luogu.org/problemnew/show/P2619 给你 ...

  10. Vue报错

    Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js 8.x Found ...