[JSOI2007]文本生成器(AC自动机,DP)
题目链接:
题目大意:给定 $n$ 个只含大写字母的串(称为可读串),问有多少种只含大写字母的长为 $m$ 的串,包含至少一个可读串。
$1\le n\le 60,1\le \text{每个串长}\le 100,1\le m\le 100$。
stmN年没发过博客了赶紧发一发
第一道在AC自动机上DP的题,纪念纪念。
首先可以发现答案就是所有串的个数减去不包含可读串的串的个数。
前半部分是 $26^m$。后半部分使用DP求解。
首先建出可读串的AC自动机。
令 $dp[i][j]$ 表示串长为 $i$,在AC自动机上走到编号为 $j$ 的节点的合法串个数。
如果走到 $j$ 的儿子 $k$ 这个节点的串合法,那么就可以从 $(i,j)$ 转移到 $(i+1,ch[j][k])$。
$dp[i+1][ch[j][k]]+=dp[i][j](0\le k<26)$
初始状态 $dp[0][0]=1$。答案为所有 $dp[m][i]$ 的最大值。
可能看到这里,你最大的疑问就是:如何判断走到点 $j$ 的串是否合法?真的可行吗?
想一想在AC自动机的fail的性质。我们就可以发现:如果从点 $j$ 不停沿fail往上跳,经过的所有点(包括 $j$)没有串尾的节点,那么 $j$ 合法,否则不合法。
这个合法性可以在BFS求fail时顺带求出。
(仔细想一想在AC自动机上跑匹配的本质就明白了)
时间复杂度 $O(m\sum|S|)$,空间复杂度 $O(\sum|S|)$,全都带一个 $26$ 的常数。
代码:
#include<bits/stdc++.h>
using namespace std;
const int mod=;
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
char ch=getchar();int x=,f=;
while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return f?-x:x;
}
int n,m,cnt,q[],h,r,ch[][],dp[][],fail[];
bool war[]; //war表示节点是否不合法(不合法!不合法!)
char str[];
void insert(char str[],int len){
int now=;
FOR(i,,len){
int p=str[i]-'A';
if(!ch[now][p]) ch[now][p]=++cnt;
now=ch[now][p];
}
war[now]=true; //串尾不合法
}
void build(){
h=;r=;
FOR(i,,) if(ch[][i]) q[++r]=ch[][i];
while(h<=r){
int u=q[h++];
FOR(i,,) if(ch[u][i]){
fail[ch[u][i]]=ch[fail[u]][i];
war[ch[u][i]]|=war[fail[ch[u][i]]];
//如果fail不合法,自己也不合法
q[++r]=ch[u][i];
}
else ch[u][i]=ch[fail[u]][i];
}
}
int qpow(int a,int b){
int ans=;
for(;b;b>>=,a=a*a%mod) if(b&) ans=ans*a%mod;
return ans;
}
int main(){
n=read();m=read();
FOR(i,,n) scanf("%s",str+),insert(str,strlen(str+));
build();
dp[][]=;
FOR(i,,m-) FOR(j,,cnt) FOR(k,,)
if(!war[ch[j][k]]) dp[i+][ch[j][k]]=(dp[i+][ch[j][k]]+dp[i][j])%mod;
//ch[j][k]合法,可以转移
int ans=qpow(,m);
FOR(i,,cnt) ans=(ans-dp[m][i]+mod)%mod; //容斥一下
printf("%d\n",ans); //答案
} AC自动机上DP
AC自动机上DP
[JSOI2007]文本生成器(AC自动机,DP)的更多相关文章
- [JSOI2007]文本生成器 --- AC自动机 + DP
[JSOI2007]文本生成器 题目描述: JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版. 该软件可以随机 ...
- BZOJ 1030: [JSOI2007]文本生成器 [AC自动机 DP]
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3953 Solved: 1614[Submit][Stat ...
- 【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个节点, ...
- [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版.该软件可以随机生成一些文章―――总是生成一篇长度固 ...
- 1030: [JSOI2007]文本生成器 ac自动机+dp
https://www.lydsy.com/JudgeOnline/problem.php?id=1030 求长度为m不包含n个子串的种数, 跑完ac自动机之后没办法跑矩阵快速幂,因为状态数比较大(6 ...
- [Bzoj1030][JSOI2007]文本生成器(AC自动机&dp)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1030 最最最常见的多串匹配问题!题目求至少包含一个子串的方案数,则可以转化成全部方案-不 ...
- BZOJ_1030_[JSOI2007]文本生成器_AC自动机+DP
BZOJ_1030_[JSOI2007]文本生成器_AC自动机+DP Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他 ...
随机推荐
- 2《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——操作文件
已经学习了基本的命令,现在是时候学习操作文件了,这也是命令行的重要任务.还是基于本教程的事先规定,本教程是入门级的,不要求熟悉类似编辑文本的程序(这些文本编辑程序,将在下个系列教程中介绍, Learn ...
- Ubuntu14.04配置gcc4.4.4+Qt4.8.4交叉编译环境
安装32位程序运行支持 sudo apt-get install lib32stdc++6 lib32z1 lib32ncurses5 lib32bz2-1.0 可能报错: lib32stdc++6 ...
- 大数据入门第二十一天——scala入门(一)并发编程Actor
注:我们现在学的Scala Actor是scala 2.10.x版本及以前版本的Actor. Scala在2.11.x版本中将Akka加入其中,作为其默认的Actor,老版本的Actor已经废弃 一. ...
- 20155318 《网络攻防》 Exp9 Web基础
20155318 <网络攻防> Exp9 Web基础 基础问题 SQL注入攻击原理,如何防御 就是通过把SQL命令插入到"Web表单递交"或"输入域名&quo ...
- 文章翻译:Recommending items to more than a billion people(面向十亿级用户的推荐系统)
Web上数据的增长使得在完整的数据集上使用许多机器学习算法变得更加困难.特别是对于个性化推荐问题,数据采样通常不是一种选择,需要对分布式算法设计进行创新,以便我们能够扩展到这些不断增长的数据集. 协同 ...
- libgdx学习记录21——Box2d物理引擎之碰撞Contact、冲量Impulse、关节Joint
Box2d中,物体可以接受力(Force).冲量(Impulse)和扭矩(Torque).这些物理元素都能改变物体的运动形式,并且默认都会唤醒物体,当然只是针对动态物体. 力是一个持久的效果,通过Bo ...
- 基于.NET Standard的分布式自增ID算法--美团点评LeafSegment
概述 前一篇文章讲述了最流行的分布式ID生成算法snowflake,本篇文章根据美团点评分布式ID生成系统文章,介绍另一种相对更容易理解和编写的分布式ID生成方式. 实现原理 Leaf这个名字是来自德 ...
- asp.net web api参数
翻译自:http://www.c-sharpcorner.com/article/parameter-binding-in-asp-net-web-api/ 主要自己学习下,说是翻译,主要是把文章的意 ...
- Go语言实现数据结构(一)单链表
1.基本释义 2.结构体设计 3.基本方法设计 4.Main函数测试 1. 基本释义 线性表包含两种存储方法:顺序存储结构和链式存储结构,其中顺序表的缺点是不便插入与删除数据:接下来我们重点实现基于G ...
- MYSQL数据库封装类
<?phpclass DBDA{ public $host="localhost"; public $uid="root"; publi ...