【Luogu】P3311数数(AC自动机上DP)
蒟蒻今天终于学会了AC自动机,感觉很稳
(后一句愚人节快乐)
这题开一个f[i][j][k]表示有没有受到限制,正在枚举第j位,来到了AC自动机的第k个节点
的方案数
随后可以刷表更新
注意如果是在枚举第一位的话注意前导0
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<queue>
#define maxl 2000
#define maxu 10
#define mod 1000000007
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} inline int count(int i){ return i-''; } int tree[maxl*maxu][maxu];
int fail[maxl*maxu];
int val[maxl*maxu];
int tot;
char c[maxl];
char s[maxl];
long long f[][maxl][maxl];
bool vis[maxl]; void update(){
int n=strlen(c+); int now=;
for(int i=;i<=n;++i){
if(tree[now][count(c[i])]==) tree[now][count(c[i])]=++tot;
now=tree[now][count(c[i])];
}
val[now]++;
return;
} void makefail(){
queue<int>q;
for(int i=;i<;++i)
if(tree[][i]) q.push(tree[][i]);
while(!q.empty()){
int from=q.front();q.pop();
for(int i=;i<;++i){
if(tree[from][i]==){
tree[from][i]=tree[fail[from]][i];
continue;
}
fail[tree[from][i]]=tree[fail[from]][i];
val[tree[from][i]]|=val[tree[fail[from]][i]];
q.push(tree[from][i]);
}
}
return;
} inline void add(long long &a,int b){
a=(a+b)%mod;
} int main(){
scanf("%s",s+);int n=strlen(s+);
int m=read();
for(int i=;i<=m;++i){
scanf("%s",c+);
update();
}
long long ans=;
makefail();
for(int i=;i<n;++i)
for(int j=;j<=tot;++j){
if(f[][i][j]){
int now=s[i+]-'';
for(int k=;k<now;++k){
int nxt=tree[j][k];
if(val[nxt]==) add(f[][i+][nxt],f[][i][j]);
}
int nxt=tree[j][now];
if(val[nxt]==) add(f[][i+][nxt],f[][i][j]);
}
if(f[][i][j]){
for(int k=;k<;++k){
int nxt=tree[j][k];
if(val[nxt]==) add(f[][i+][nxt],f[][i][j]);
}
}
if(j==){
if(i==){
int now=s[i+]-'';
for(int k=;k<now;++k){
int nxt=tree[j][k];
if(val[nxt]==) add(f[][i+][nxt],);
}
int nxt=tree[j][now];
if(val[nxt]==) add(f[][i+][nxt],);
}
else{
for(int k=;k<;++k){
int nxt=tree[j][k];
if(val[nxt]==) add(f[][i+][nxt],);
}
}
}
}
for(int i=;i<=tot;++i){
add(ans,f[][n][i]);
add(ans,f[][n][i]);
}
ans=(ans+mod)%mod;
printf("%lld\n",ans);
}
【Luogu】P3311数数(AC自动机上DP)的更多相关文章
- 【洛谷4045】[JSOI2009] 密码(状压+AC自动机上DP)
点此看题面 大致题意: 给你\(n\)个字符串,问你有多少个长度为\(L\)的字符串,使得这些字符串都是它的子串.若个数不大于\(42\),按字典序输出所有方案. 状压 显然,由于\(n\)很小,我们 ...
- bzoj [Sdoi2014]数数 AC自动机上dp
[Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1264 Solved: 636[Submit][Status][Discu ...
- Passwords Gym - 101174E (AC自动机上DP)
Problem E: Passwords \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 给出两个正整数\(A,B\),再给出\(n\)个字符 ...
- URAL 1158 AC自动机上的简单DP+大数
题目大意 在一种语言中的字母表中有N(N<=50)个字母,每个单词都由M(M<=50)个字母构成,因此,一共可以形成N^M个单词.但是有P(P<=10)个串是被禁止的,也就是说,任何 ...
- bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)
bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...
- 【JZOJ3624】【SDOI2014】数数(count) AC自动机+数位dp
题面 100 容易想到使用AC自动机来处理禁忌子串的问题: 然后在自动机上数位dp,具体是: \(f_{i,j,0/1}\)表示填了\(i\)位,当前在自动机的第\(j\)个结点上,\(0\)表示当前 ...
- 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 682 Solved: 364 Description 我们称一 ...
- POJ 3691 AC自动机上的dp
题目大意: 给定一些不合理的DNA序列,再给一段较长的dna序列,问最少修改几次可以使序列中不存在任何不合理序列,不能找到修改方法输出-1 这里你修改某一个点的DNA可能会影响后面,我们不能单纯的找匹 ...
- 【BZOJ1030】[JSOI2007] 文本生成器(AC自动机上跑DP)
点此看题面 大致题意: 给你\(N\)个字符串(只含大写字母),要你求出有多少个由\(M\)个大写字母构成的字符串含有这\(N\)个字符串中的至少一个. \(AC\)自动机 看到题目,应该比较容易想到 ...
随机推荐
- MVC web api转换JSON 的方法
- CVE-2011-0065
环境 备注 操作系统 Windows 7 x86 sp1 专业版 漏洞软件 Firefox 版本号:3.6.16 调试器 Windbg 版本号:6.12.0002.633 0x00 漏洞描述 在F ...
- Java字符串池(String Pool)深度解析(转)
出自 http://www.cnblogs.com/fangfuhai/p/5500065.html 在工作中,String类是我们使用频率非常高的一种对象类型.JVM为了提升性能和减少内存开销,避 ...
- C# 用qq邮箱发邮件
一.在企业的QQ邮箱中开启POP3/SMTP服务 开启服务时,授权密码保存好. 二.示例 public static string UserName = ""; // 企业邮箱 p ...
- 使用filter函数筛选出素数
function getPrimeNumber(arr) { return arr.filter(function (number) { if (typeof number !== 'number' ...
- Android驱动开发读书笔记五
第五章 本章介绍了S3C6410开发板的功能,开发板的不同主要是在烧录嵌入式系统的方式不同,以及如何在此开发板上安装Android. 1.安装串口调试工具minicom 首先需要一根USB转串口线,由 ...
- 八皇后问题(DFS)
题目描述: 要在国际象棋棋盘中放八个皇后,使任意两个皇后都不能互相吃,皇后能吃同一行.同一列,同一对角线上(两个方向的对角线)的任意棋子.现在给一个整数n(n<=92),输出前n种的摆法. 输入 ...
- ubuntu安装easygui模块
使用pip安装easygui 如果未安装pip,则使用如下命令 sudo apt-get install python-pip 安装完pip后,使用如下命令安装easygui sudo pip ins ...
- 无法重启ssh
rm /dev/null mknod /dev/null c 1 3 chmod 666 /dev/null
- Python基础——数值
运算 运算 运算符 示例 加 + 减 - 乘 * 除 / 取余 % 幂 ** 赋值 = 绝对值 abs 取整(四舍五入) round 最大值 max 最小值 min 科学计数法 e 十六进制 0x 逻 ...