【BZOJ-1030】文本生成器 AC自动机 + DP
1030: [JSOI2007]文本生成器
Time Limit: 1 Sec Memory Limit: 162 MB
Submit:
3253 Solved: 1330
[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
Solution
字符串,首先想到AC自动机,方案数?想到DP
读入串,建Trie树,建出Fail指针
直接DP求满足的方案数似乎不太容易,不妨转换一下思路
应用补集的思想,求不满足的方案数,与总方案数做差即可,那么遍可以DP
$f[i][j]$表示的是匹配到第i个位置在AC自动机上的j点,转移不是很难想
那么利用快速幂计算一下总方案数,枚举一下$\sum f[m][i]$,做差及为答案
值得注意的地方:对于Fail指针指向的点,如果是end,那么当前点同样为end
Code
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- #define p 10007
- #define N 10010
- int sz,son[N][],fail[N],q[N],loc[N],f[][N],n,m,ans;bool end[N];
- void clear()
- {
- sz=;
- for (int i=; i<=; i++) son[][i]=;
- }
- void insert(char s[])
- {
- int x=;
- for (int i=; i<strlen(s); i++)
- {
- if (!son[x][s[i]-'A'+]) son[x][s[i]-'A'+]=++sz,x=sz;
- else x=son[x][s[i]-'A'+];
- }
- end[x]=;
- }
- void buildfail()
- {
- int head=,tail=; q[]=; fail[]=;
- while (head<tail)
- {
- int now=q[head++];
- for (int i=; i<=; i++)
- {
- if (!son[now][i]) continue;
- int ff=fail[now];
- while(!son[ff][i]) ff=fail[ff];
- fail[son[now][i]]=son[ff][i];
- if (end[son[ff][i]]) end[son[now][i]]=;
- q[tail++]=son[now][i];
- }
- }
- }
- int quick_pow(int x,int y)
- {
- long long re=;
- for (int i=y; i; i>>=,x=x*x%p)
- if (i&) re=re*x%p;
- return (int)re;
- }
- int main()
- {
- clear(); char s[N];
- scanf("%d%d",&n,&m);
- for (int i=; i<=n; i++)
- scanf("%s",s),insert(s);
- buildfail();
- f[][]=;
- for (int i=; i<=m; i++)
- for (int j=; j<=sz; j++)
- if (!end[j] && f[i-][j])
- for (int k=; k<=; k++)
- {
- int tmp=j;
- while (!son[tmp][k]) tmp=fail[tmp];
- f[i][son[tmp][k]]+=f[i-][j];
- f[i][son[tmp][k]]%=p;
- }
- for (int i=; i<=sz; i++)
- if (!end[i]) ans+=f[m][i],ans%=p;
- int tot=quick_pow(,m);
- printf("%d\n",(tot-ans+p)%p);
- return ;
- }
我觉得吧,我还得学习一个
【BZOJ-1030】文本生成器 AC自动机 + DP的更多相关文章
- [bzoj] 1030 文本生成器 || AC自动机+dp
原题 给出n个字符串,求随机生成一个m长度的字符串,有多少个是可辨识的(即出现了n个字符串中的任意字符串) 正难则反 求有多少个不可辨识的,26^m-不可辨识即为答案 f[i][j]表示填到第i个字符 ...
- bzoj1030 文本生成器(AC自动机+dp)
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4777 Solved: 1986[Submit][Stat ...
- [JSOI2007]文本生成器 --- AC自动机 + DP
[JSOI2007]文本生成器 题目描述: JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版. 该软件可以随机 ...
- 【bzoj1030】[JSOI2007]文本生成器 AC自动机+dp
题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是生成一篇长度固 ...
- 洛谷P4052 [JSOI2007]文本生成器 AC自动机+dp
正解:AC自动机+dp 解题报告: 传送门! 感觉AC自动机套dp的题还挺套路的,,, 一般就先跑遍AC自动机,然后就用dp dp的状态一般都是f[i][j]:有i个字符,是ac自动机上的第j个节点, ...
- BZOJ 1030: [JSOI2007]文本生成器 [AC自动机 DP]
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3953 Solved: 1614[Submit][Stat ...
- 1030: [JSOI2007]文本生成器 ac自动机+dp
https://www.lydsy.com/JudgeOnline/problem.php?id=1030 求长度为m不包含n个子串的种数, 跑完ac自动机之后没办法跑矩阵快速幂,因为状态数比较大(6 ...
- [BZOJ1030] [JSOI2007] 文本生成器 (AC自动机 & dp)
Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...
- [BZOJ1030]:[JSOI2007]文本生成器(AC自动机+DP)
题目传送门 题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...
随机推荐
- liunx中的进程与线程
1. 进程和线程 进程和线程是程序运行时状态,是动态变化的,进程和线程的管理操作(比如,创建,销毁等)都是有内核来实现的. Linux中的进程于Windows相比是很轻量级的,而且不严格区分进程和线程 ...
- SSH框架总结(框架分析+环境搭建+实例源码下载) 《转》
这篇文章比较易懂,易理解: 首先,SSH不是一个框架,而是多个框架(struts+spring+hibernate)的集成,是目前较流行的一种Web应用程序开源集成框架,用于构建灵活.易于扩展的多层W ...
- Android 多线程----AsyncTask异步任务详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
- mysql乱码的好文
1. http://www.blogjava.net/wldandan/archive/2007/09/04/142669.html 2. http://www.111cn.net/database/ ...
- Volley(六 )—— 从源码带看Volley的缓存机制
磁盘缓存DiskBasedCache 如果你还不知道volley有磁盘缓存的话,请看一下我的另一篇博客请注意,Volley已默认使用磁盘缓存 DiskBasedCache内部结构 它由两部分组成,一部 ...
- String类常用方法。
一,字符数组与字符串. 一个字符串可以变成一个字符数组,同样,一个字符数组可以变成一个字符串. 在String类中提供了以下操作方法. 1)将字符串变成字符数组:public char[] toCha ...
- 【转】【WPF】 WPF 调用API修改窗体风格实现真正的无边框窗体
WPF中设置无边框窗体似乎是要将WindowStyle设置为None,AllowTransparency=true,这样才能达到WinForm中无边框窗体的样式.但是AllowTransparency ...
- Groovy Spock环境的安装
听说spock是一个加强版的Junit,今天特地安装了,再把过程给大家分享一下. 首先说明,我的Java项目是用maven管理的. 我用的Eclipse是Kelper,开普勒. 要使用Spock之前, ...
- Contains Duplicate
Given an array of integers, find if the array contains any duplicates. Your function should return t ...
- PHP基础14:表单处理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...