[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一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他 ...
随机推荐
- 动画:view从点逐渐变大(放大效果)
-(void) animationAlert:(UIView *)view { CAKeyframeAnimation *popAnimation = [CAKeyframeAnimation ani ...
- 利用Cydia Substrate进行Android HOOK
Cydia Substrate是一个代码修改平台.它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的.而Xposed只支持HOOK app_process中的java ...
- 20155305《网络对抗》Web安全基础实践
20155305<网络对抗>Web安全基础实践 基础问题回答 SQL注入攻击原理,如何防御? 原理:SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL ...
- Android开发——高斯模糊效果的简单实现
0. 前言 在Android开发中,经常在音乐软件中看到高斯模糊效果. 在找遍了所有高斯模糊的算法代码后,发现stackblur的Java实现是最快的.效果如下所示. 1. 高斯模糊效果实现 Bit ...
- eclipse + maven + com.sun.jersey 创建 restful api
maven 创建 jersey 项目 如果没找到 jersey archetype, 下载 maven 的 archetype xml, 然后导入 archetypes 运行 右击 main.java ...
- 爱普生L313彩色打印相片
操作环境: windows 和MAC 一.普通打印(默认选项) 1.爱普生L313 普通默认打印为快速不清晰打印. 2.以上打印效果出来图片比较快速出图,但是清晰度不够 二.照片打印设置 1.照片设置 ...
- github添加ssh连接用户
最近打算用flask写一个自己的博客网站,打算把代码放在GitHub上,使用ssh访问.记录下GitHub配置ssh用户的流程. 1.在本地电脑或云服务器上生成ssh公钥和私钥,window下可以进入 ...
- python类属性在继承中的修改的影响
class A(object): x = 1 class B(A): pass class C(A): pass # 通过父类修改类属性,子类继承的类属性也改变 A.x = 3 print(A.x, ...
- @JsonFormat时间格式化注解使用
@JsonFormat注解是一个时间格式化注解,比如我们存储在mysql中的数据是date类型的,当我们读取出来封装在实体类中的时候,就会变成英文时间格式,而不是yyyy-MM-dd HH:mm:ss ...
- 1079. Total Sales of Supply Chain (25)-求数的层次和叶子节点
和下面是同类型的题目,只不过问的不一样罢了: 1090. Highest Price in Supply Chain (25)-dfs求层数 1106. Lowest Price in Supply ...