【题目大意】

给出单词总数和固定的文章长度M,求出至少包含其中一个单词的可能文章数量。

【思路】

对于至少包含一个的类型,我们可以考虑补集。也就是等于[总的文章可能性总数-不包含任意一个单词的文章总数]有两个注意点:

1.Trie图+DP。Trie图和AC自动机的区别在于,当孩子i为NULL时,则让孩子指针等于fail指针的孩子i,这样就可以继续匹配下去了。因此寻找fail指针的时候,可以不用循环而用判断语句即可。

2.danger表示当前位置包含了单词,所以DP的时候舍去。如果你指向的fail指针是danger的,也就是你的后缀是danger的,那么当前的也是danger的。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN=+;
const int MAXM=+;
const int MOD=;
const int NUMA=;
int n,m,cnt=;
struct ACauto
{
int id;
int danger;
ACauto* next[NUMA];
ACauto* fail;
ACauto()
{
danger=;
id=++cnt;
for (int i=;i<NUMA;i++) next[i]=NULL;
fail=NULL;
}
};
ACauto* node[MAXN*MAXM];
int f[MAXN][MAXM*MAXN]; void insert(ACauto* root,char* str)
{
int len=strlen(str);
ACauto* tmp=root; for (int i=;i<len;i++)
{
int index=str[i]-'A';
if (tmp->next[index]==NULL)
{
tmp->next[index]=new ACauto;
node[cnt]=tmp->next[index];
}
tmp=tmp->next[index];
}
tmp->danger=;
} void build(ACauto* root)
{
queue<ACauto*> que;
que.push(root);
while (!que.empty())
{
ACauto* head=que.front();que.pop();
for (int i=;i<NUMA;i++)
{
if (head->next[i]==NULL)
{
if (head==root) head->next[i]=root;
else head->next[i]=head->fail->next[i];
}
else
{
if (head==root) head->next[i]->fail=root;
else
{
head->next[i]->fail=head->fail->next[i];
if (head->next[i]->fail->danger) head->next[i]->danger=;/*注意!*/
}
que.push(head->next[i]);
}
}
}
} void dp(ACauto* root)
{
memset(f,,sizeof(f));
f[][]=;
for (int i=;i<=m-;i++)
for (int j=;j<=cnt;j++)
{
if (!node[j]->danger && f[i][j])
{
for (int k=;k<NUMA;k++)//枚举下一个字母
if (!node[j]->next[k]->danger)
f[i+][node[j]->next[k]->id]=(f[i][j]+f[i+][node[j]->next[k]->id])%MOD;
}
}
} void findres()
{
int ans1=,ans2=;
for (int i=;i<=cnt;i++)
if (!node[i]->danger) ans1=(ans1+f[m][i])%MOD;
for (int i=;i<=m;i++) ans2=(ans2*NUMA)%MOD;
cout<<(ans2-ans1+MOD)%MOD<<endl;
} int main()
{
char str[MAXN];
ACauto* root=new ACauto;
node[]=root;
scanf("%d%d",&n,&m);
for (int i=;i<n;i++)
{
scanf("%s",str);
insert(root,str);
} build(root);
dp(root);
findres();
return ;
}

【Trie图+DP】BZOJ1030[JSOI2007]-文本生成器的更多相关文章

  1. BZOJ1030 JSOI2007 文本生成器 【AC自动机】【DP】*

    BZOJ1030 JSOI2007 文本生成器 Description JSOI交给队员ZYX一个任务,编制一个称之为"文本生成器"的电脑软件:该软件的使用者是一些低幼人群,他们现 ...

  2. [Bzoj1030][JSOI2007]文本生成器(AC自动机)(dp)

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5254  Solved: 2172[Submit][Stat ...

  3. bzoj1030 [JSOI2007]文本生成器

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2654  Solved: 1100[Submit][Stat ...

  4. BZOJ1030: [JSOI2007]文本生成器(Trie图+dp)

    Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  5. [BZOJ1030] [JSOI2007] 文本生成器 (AC自动机 & dp)

    Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  6. BZOJ1030[JSOI2007]文本生成器——AC自动机+DP

    题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是生成一篇长度固 ...

  7. [BZOJ1030]:[JSOI2007]文本生成器(AC自动机+DP)

    题目传送门 题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  8. BZOJ1030: [JSOI2007]文本生成器(AC自动机)

    Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5984  Solved: 2523[Submit][Status][Discuss] Descripti ...

  9. BZOJ1030 [JSOI2007]文本生成器[DP+AC自动机]

    我学到现在才是初三学弟的水平..哭 这里相当于求长度为$m$的,字符集$\{A...Z\}$的且不包含任一模式串的文本串个数.这是一个典型的AC自动机匹配计数问题. 设$f_{i,j}$表示在AC自动 ...

随机推荐

  1. C#反射动态调用dll中的方法及使用QuartZ.net实现作业调度

    using Quartz; using Quartz.Impl; using System; using System.Collections.Generic; using System.Linq; ...

  2. C基础 redis缓存访问

    引言 先说redis安装, 这里采用的环境是. Linux version --generic (buildd@lgw01-) (gcc version (Ubuntu -14ubuntu2) ) # ...

  3. IIS配置PHP环境(快速最新版)(转载+自创)

    (参考转载的) 我们知道php配置有几种: 1.CGI方式加载PHP环境,通常就是IIS里面配置解释器为php.exe,早期比较常见,目前使用较少. 特点是:稳定,但效率太低. 2.ISAPI方式加载 ...

  4. FineReport——发送邮件

    在FR中,个用户之间可以通过邮件的形式进行通信,但是存在一个问题就是FineReport平台只能设置一个发件人账户,收件人账户可以有多个. 所以在实际的系统开发中可能需要自己开发信息交互的模块. 在系 ...

  5. vsftpd 虚拟用户配置

    vsftpd 虚拟用户的作用是 通过不同的虚拟用户可以有不同的根目录. 从 2.3.5 版本之后,vsftpd增强了安全检查,如果用户被限定在了其主目录下,则该用户的主目录不能在具有写权限了,如果检查 ...

  6. python库-urllib

    urllib库提供了一系列操作url的功能,是python处理爬虫的入门级工具,网上的学习资料也很多.我做爬虫是一开始就用了Scrapy框架,并不是一步步从urllib开始的,反而是在后来解决一些小问 ...

  7. review的一个收获popstate,addEventListener:false ,split,jquery cache

    一.popstate:记录url历史变化 二.document.location.hash:锚点后面的东西 三.addEventListener:false 是否在捕获或者冒泡事件中执行 强转换 四. ...

  8. hdu 1806(线段树区间合并)

    Frequent values Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  9. hdu5756

    http://www.cnblogs.com/duoxiao/p/5777644.html 官方题解在这里 其实这道题不难,当初训练的时候不会做说明自己太弱 lazy标记不pushdown就是用laz ...

  10. 【剑指offer】面试题 55. 二叉树的深度

    面试题 55. 二叉树的深度 题目一:二叉树的深度 题目描述:输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. Java 实现 ...