Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 5984  Solved: 2523
[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

感觉自己好菜啊这种题都想不出来qwq。。

刚开始想的是容斥—>把所有合法的统计出来再减去重复的!!没错我就这么xjb容斥了半个小时qwq。。

看了一下大佬的题解瞬间思路明了。。。

考虑经典补集转化思想:这题问的是可读的,我们可以转化为总的-不可读的。

总的就是$26^m$

不可读的考虑DP。设$f[i][j]$表示长度为$i$时,在自动机上第$j$个位置有多少不可读的情况

开始时$f[0][0] = 1$,转移的时候枚举一下出边

注意!!如果一个点的$fail$指针指向的位置不可读,那么该节点也是不可读的!

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
const int MAXN = 1e5 + , B = , mod = ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, M;
int ch[MAXN][], fail[MAXN], tot = , root = , val[MAXN];
char s[];
void insert(char *s) {
int N = strlen(s + ), now = root;
for(int i = ; i <= N; i++) {
int x = s[i] - 'A';
if(!ch[now][x]) ch[now][x] = ++tot;
now = ch[now][x];
}
val[now] = ;//不能经过
}
void GetFail() {
queue<int> q;
for(int i = ; i < B; i++) if(ch[root][i]) q.push(ch[root][i]);
while(!q.empty()) {
int p = q.front(); q.pop();
for(int i = ; i < B; i++)
if(ch[p][i]) fail[ch[p][i]] = ch[fail[p]][i], q.push(ch[p][i]);
else ch[p][i] = ch[fail[p]][i];
val[p] |= val[fail[p]];
}
}
int f[][MAXN]; // 当前长度为i,在自动机的地j号节点
int solve() {
f[][] = ;
for(int i = ; i <= M; i++) {
for(int j = ; j <= tot; j++) {
for(int k = ; k < B; k++) {//枚举出边
int son = ch[j][k];
if(val[son]) continue;
f[i][son] = (f[i][son] % mod+ f[i - ][j] % mod) % mod;
}
}
}
int ans = ;
for(int i = ; i <= tot; i++)
ans = (ans + f[M][i] % mod) % mod;
int sum = ;
for(int i = ; i <= M; i++) sum = ( * sum) % mod;
return (sum - ans + mod) % mod;
}
main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
#endif
scanf("%d %d", &N, &M);
for(int i = ; i <= N; i++)
scanf("%s", s + ), insert(s);
GetFail();
printf("%d", solve() % mod);
}

BZOJ1030: [JSOI2007]文本生成器(AC自动机)的更多相关文章

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

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

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

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

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

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

  4. BZOJ1030 [JSOI2007]文本生成器 AC自动机 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1030 题意概括 给出n个模式串,问长度为m的串中有多少个至少含有这n个模式串中的任意一个. 注意, ...

  5. [bzoj1030][JSOI2007]文本生成器——AC自动机

    Brief Description 给定一些模式串,您需要求出满足以下要求的字符串的个数. 长度为m 包含任意一个模式串 Algorithm Design 以下内容来自神犇博客 首先运用补集转换,转而 ...

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

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1030 最最最常见的多串匹配问题!题目求至少包含一个子串的方案数,则可以转化成全部方案-不 ...

  7. 【BZOJ1030】[JSOI2007]文本生成器 AC自动机+动态规划

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

  8. 【BZOJ-1030】文本生成器 AC自动机 + DP

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

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

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

随机推荐

  1. mysql无法连接Can't create a new thread (errno 11)

    问题描述: 今天本地navicat连接服务器mysql出错 ,提示ERROR 1135: Can't create a new thread (errno 11); if you are not ou ...

  2. Angular选项卡

    前几天我发的东西,可能对于没有基础的人很难理解,那么今天,咱们就发点简单点的东西吧! Angular显示隐藏,选项卡! 还是那句话,话不多说,上代码: <!DOCTYPE html> &l ...

  3. js添加、修改、删除xml节点例子

    version="1.0" encoding="gb2312"?> . <bookstore> . <book genre=" ...

  4. Highcharts error #14: www.highcharts.com/errors/14

    错误原因:数据类型错误,需要的是Number类型,传入的却是String 以为为官网说明: Highcharts Error #14 String value sent to series.data, ...

  5. 标头停止点不能位于宏或#if块中.

    使用VS2010在项目中编写C++头文件**.h时提示: PCH 警告: 标头停止点不能位于宏或#if块中 原因:vs2010的智能感知要求.h必须以非#if系列的预编译指令打头 正确方法:将所有含有 ...

  6. Tcpdump usage examples

    In most cases you will need root permission to be able to capture packets on an interface. Using tcp ...

  7. SpringMVC方法接收参数可以为空、默认值设置

  8. WCF 的优势和特点

    版权声明:本文为博主原创文章,未经博主允许不得转载. 一.理解面向服务(Service-Oriented-Architecture)    是指为了解决在Internet环境下业务集成的需要,通过连接 ...

  9. TinkPHP去重统计查询

    当统计一个有重复的字段可以用这个方法 $count = $model->where($map)->count('distinct(id)'); 转自 http://www.thinkphp ...

  10. Python3循环语句

    Python3 循环语句 Python中的循环语句有for和while. 循环语句控制结构图如下: 一.while循环 ①循环结构 while 判断条件: 执行语句 实例: n = int(input ...