BZOJ1030: [JSOI2007]文本生成器(AC自动机)
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
A
B
Sample Output
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自动机)的更多相关文章
- [BZOJ1030] [JSOI2007] 文本生成器 (AC自动机 & dp)
		
Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...
 - [BZOJ1030]:[JSOI2007]文本生成器(AC自动机+DP)
		
题目传送门 题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...
 - BZOJ1030[JSOI2007]文本生成器——AC自动机+DP
		
题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是生成一篇长度固 ...
 - BZOJ1030 [JSOI2007]文本生成器  AC自动机  动态规划
		
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1030 题意概括 给出n个模式串,问长度为m的串中有多少个至少含有这n个模式串中的任意一个. 注意, ...
 - [bzoj1030][JSOI2007]文本生成器——AC自动机
		
Brief Description 给定一些模式串,您需要求出满足以下要求的字符串的个数. 长度为m 包含任意一个模式串 Algorithm Design 以下内容来自神犇博客 首先运用补集转换,转而 ...
 - [Bzoj1030][JSOI2007]文本生成器(AC自动机&dp)
		
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1030 最最最常见的多串匹配问题!题目求至少包含一个子串的方案数,则可以转化成全部方案-不 ...
 - 【BZOJ1030】[JSOI2007]文本生成器 AC自动机+动态规划
		
[BZOJ1030][JSOI2007]文本生成器 Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文 ...
 - 【BZOJ-1030】文本生成器    AC自动机 + DP
		
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3253 Solved: 1330[Submit][Stat ...
 - [JSOI2007]文本生成器 --- AC自动机 + DP
		
[JSOI2007]文本生成器 题目描述: JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版. 该软件可以随机 ...
 
随机推荐
- Java中的锁之乐观锁与悲观锁
			
1. 分类一:乐观锁与悲观锁 a)悲观锁:认为其他线程会干扰本身线程操作,所以加锁 i.具体表现形式:synchronized关键字和lock实现类 b)乐观锁:认为没有其他线程会影响本身线程操作, ...
 - C#利用事件与委托进行窗体间传值简单小例子
			
本篇博客是利用C#委托与事件进行窗体间传值的简单小例子 委托与事件的详细解释大家可以参照张子阳的博客: http://www.tracefact.net/CSharp-Programming/Dele ...
 - mysql 字符串转换呈毫秒值
			
SELECT CEIL((UNIX_TIMESTAMP('2011-05-31 23:59:59') - UNIX_TIMESTAMP('2011-05-31 00:59:59'))/1000/60/ ...
 - 前端小课堂 js:what is the function?
			
js 函数: 概念:函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. 说白了就是响应用户操作所执行的代码,通过js事件触发,然后调用执行函数里代码的操作. 比如常见的用户点击事件,用户点击 ...
 - 关于Android中的ViewTreeObserver
			
ViewTreeObserver结构 extends Object java.lang.Object ↳ android.view.ViewTreeObserver ViewTreeObserver概 ...
 - MonkeyRunnermac
			
http://blog.csdn.net/wyb199026/article/details/51436754 背景 之前想学习自动化测试的时候,就研究过MonkeyRunner,说实话MonkeyR ...
 - win7+jdk1.6+solr4.7.2在内嵌jetty servelt或外置tocmat服务器的solr服务使用
			
solr安装,目前初步接触solr,了解两种启动方式.一种是自带的jetty,另一种是基于tomcat.由于超过4.7.2版本的solr需要java1.7及以上版本的支持,所以我们选择solr ...
 - 序列化Serializable
			
public interface Serializable 类的序列化由实现java.io.Serializable接口的类启用. 不实现此接口的类将不会使任何状态序列化或反序列化. 可序列化类的所有 ...
 - ASP.NET中引用dll“找不到指定模块"的完美解决办法 z
			
DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息.DllImport属性应用于方法,要求最少要 ...
 - 第二次Surm冲刺
			
一.小组完成情况: 因为技术原因,小组部分代码还没有完成,现在已经可以实现简单的借书与还书操作. 二.个人情况 我对代码进行了测试,与大家进相关的讨论. 三.总结 这次实验的团队合作真的很重要,有许多 ...