BZOJ1030 [JSOI2007]文本生成器[DP+AC自动机]
我学到现在才是初三学弟的水平。。哭
这里相当于求长度为$m$的,字符集$\{A...Z\}$的且不包含任一模式串的文本串个数。这是一个典型的AC自动机匹配计数问题。
设$f_{i,j}$表示在AC自动机上面走了$i$步在$j$点的方案数。
注意由于不能包含任一模式串,也就是说任意时刻都不能项后缀含有模式串的点上走,也就是fail树上所有以模式串结尾点为根的子树上的点。
这个可以在建立fail树的时候附带标记好。
于是转移的时候枚举字符集,下一步可以走向合法节点则转移之,否则不转移。边界$f_{0,0}=1$。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define dbg(x) cerr << #x << " = " << x <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int P=,N=+;
char s[+];
int tr[N][],nxt[N],ban[N],bin[N],tot,cnt;
int f[+][N];
int n,m,ans;
inline void Insert(){
int len=strlen(s+),x=;
for(register int i=,c=s[]-'A';i<=len;++i,c=s[i]-'A'){
if(!tr[x][c])tr[x][c]=++tot;
x=tr[x][c];
}
ban[x]=;
}
queue<int> q;
inline void Build(){
bin[cnt=]=;
for(register int i=;i<;++i)if(tr[][i])nxt[tr[][i]]=,q.push(tr[][i]);
while(!q.empty()){
int x=q.front();q.pop();
if(ban[nxt[x]])ban[x]=;
if(!ban[x])bin[++cnt]=x;
for(register int i=;i<;++i){
if(tr[x][i])nxt[tr[x][i]]=tr[nxt[x]][i],q.push(tr[x][i]);
else tr[x][i]=tr[nxt[x]][i];
}
}
}
inline void add(int&A,int B){A+=B;A>=P&&(A-=P);}
inline int fpow(int x,int p){int ret=;for(;p;p>>=,x=x*x%P)if(p&)ret=ret*x%P;return ret;}
inline void dp(){
f[][]=;
for(register int i=;i<m;++i)
for(register int j=;j<=cnt;++j)if(f[i][bin[j]])
for(register int k=;k<;++k)if(!ban[tr[bin[j]][k]])
add(f[i+][tr[bin[j]][k]],f[i][bin[j]]);
} int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n),read(m);
for(register int i=;i<=n;++i)scanf("%s",s+),Insert();
Build();
dp();
for(register int i=;i<=cnt;++i)add(ans,f[m][bin[i]]);
printf("%d\n",(fpow(,m)-ans+P)%P);
return ;
}
这里使用AC自动机位置描述状态,是为了有效满足合法性。注意。
BZOJ1030 [JSOI2007]文本生成器[DP+AC自动机]的更多相关文章
- BZOJ1030 JSOI2007 文本生成器 【AC自动机】【DP】*
BZOJ1030 JSOI2007 文本生成器 Description JSOI交给队员ZYX一个任务,编制一个称之为"文本生成器"的电脑软件:该软件的使用者是一些低幼人群,他们现 ...
- [Bzoj1030][JSOI2007]文本生成器(AC自动机)(dp)
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5254 Solved: 2172[Submit][Stat ...
- bzoj1030: [JSOI2007]文本生成器(AC自动机+DP)
第一次写这类题...懵 直接计算答案不好计算,所以补集转化求不合法的方案. 首先考虑朴素的DP,设$f(i, s)$表示前$i$个字符,字符串为$s$的方案数,且任意一个给定串都不存在$s$中. 我们 ...
- BZOJ1030 [JSOI2007]文本生成器(AC自动机)
做到了AC自动机的题目,复习了一下AC自动机,学习了黄学长代码,这个题呢,我们可以模拟在AC自动机上的操作,dp数组f[i][j]表示前i个字符,我们在AC自动机上处在j号节点的方案数. 我们可以计算 ...
- 2021.11.11 P4052 [JSOI2007]文本生成器(AC自动机+DP)
2021.11.11 P4052 [JSOI2007]文本生成器(AC自动机+DP) https://www.luogu.com.cn/problem/P4052 题意: JSOI 交给队员 ZYX ...
- 【BZOJ1030】文本生成器(AC自动机,动态规划)
[BZOJ1030]文本生成器(AC自动机,动态规划) 题面 BZOJ 题解 超级简单良心送分题 很明显是所有状态-不合法状态 合法状态就是\(26^m\) 不合法状态做一个\(dp\)就好 #inc ...
- 【bzoj1030】: [JSOI2007]文本生成器 字符串-AC自动机-DP
[bzoj1030]: [JSOI2007]文本生成器 首先把匹配任意一个的个数的问题转化为总个数-没有一个匹配的个数 先构造AC自动机,然后枚举每一位的字母以及在自动机上的位置 f[i][j]为第i ...
- 【洛谷 P4052】 [JSOI2007]文本生成器(AC自动机,DP)
题目链接 AC自动机上dp第一题嗷. 如果直接求可读文本的数量,显然要容斥,不好搞. 于是考虑求不可读文本的数量,再用\(26^m\)减去其即可. 建出AC自动机,如果一个节点为单词结尾或其fail链 ...
- bzoj 1030 [JSOI2007]文本生成器(AC自动机+DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题意] 给n个小串,随机构造一个长为m的大串,一个串合法当且仅当包含一个或多个 ...
随机推荐
- IntelliJ IDEA 2019.2.1 破解教程, 最新激活码(激活到2089年8月,亲测有效,持续更新中...)
当前最新版本 IDEA 2019.2.1 本来笔者这边是有个正版激活码可以使用的,但是,2019.9月3号的时候,一些小伙伴反映这个注册码已经失效了,于是拿着自己的 IDEA, 赶快测试了一下,果不其 ...
- MySQL: 1006 - Can't create database '***' (errno: 13) 错误 解决方法
原文连接:https://blog.csdn.net/kexiaoling/article/details/50259569 如果使用root账号登录到数据库create database时提错错误: ...
- 并发-synchronized
线程并发-synchronized和Lock简单认知 前几天刚加深了线程的了解,期间在验证各种方法及多线程时遇到一些疑问,在高并发的情况下,怎么做才能保证程序还能按照我们预期的正常运行下去,这就是我们 ...
- 【Python】【基础知识】【内置函数】【print的使用方法】
原英文帮助文档: print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) Print objects to the text ...
- 【LOJ】#3090. 「BJOI2019」勘破神机
LOJ#3090. 「BJOI2019」勘破神机 为了这题我去学习了一下BM算法.. 很容易发现这2的地方是\(F_{1} = 1,F_{2} = 2\)的斐波那契数列 3的地方是\(G_{1} = ...
- [POI2011]ROT-Tree Rotations 题解
题面 这道题咋看都是无法从dp入手,那么就从数据结构入手!: 首先你要会权值线段树和线段树合并. 然后你要知道: 对于任意一个节点,交换左右子树对当前节点和前面的所有节点没有影响. 因为这是前序遍历: ...
- Invoker(小DP)
题意:http://acm.hdu.edu.cn/showproblem.php?pid=6739 尽量让他们连起来. 思路: 直接dp,其中一个状态是以什么结尾. #define IOS ios_b ...
- 代理、反射、注解、hook
代理 通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,扩展目标对象的功能. 代理对象拦截真实对象的方法调用,在真实对象调用前/后实现自己的逻辑调用 这里使用到编程中的一个思想:不 ...
- 并不对劲的复健训练-CF1187D
题目大意 有两个长度为\(n\)的序列\(a_1,...,a_n\),\(b_1,...,b_n\)(\(a,b\leq n\leq 3\times 10^5\) ).一次操作是选取 \([l,r]\ ...
- BufferedImage类、Image类、Graphics类
BufferedImage Image是一个抽象类,BufferedImage是其实现类,是一个带缓冲区图像类,主要作用是将一幅图片加载到内存中(BufferedImage生成的图片在内存里有一个图像 ...