题目链接

  蒟蒻今天终于学会了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)的更多相关文章

  1. 【洛谷4045】[JSOI2009] 密码(状压+AC自动机上DP)

    点此看题面 大致题意: 给你\(n\)个字符串,问你有多少个长度为\(L\)的字符串,使得这些字符串都是它的子串.若个数不大于\(42\),按字典序输出所有方案. 状压 显然,由于\(n\)很小,我们 ...

  2. bzoj [Sdoi2014]数数 AC自动机上dp

    [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1264  Solved: 636[Submit][Status][Discu ...

  3. Passwords Gym - 101174E (AC自动机上DP)

    Problem E: Passwords \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 给出两个正整数\(A,B\),再给出\(n\)个字符 ...

  4. URAL 1158 AC自动机上的简单DP+大数

    题目大意 在一种语言中的字母表中有N(N<=50)个字母,每个单词都由M(M<=50)个字母构成,因此,一共可以形成N^M个单词.但是有P(P<=10)个串是被禁止的,也就是说,任何 ...

  5. bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)

    bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...

  6. 【JZOJ3624】【SDOI2014】数数(count) AC自动机+数位dp

    题面 100 容易想到使用AC自动机来处理禁忌子串的问题: 然后在自动机上数位dp,具体是: \(f_{i,j,0/1}\)表示填了\(i\)位,当前在自动机的第\(j\)个结点上,\(0\)表示当前 ...

  7. 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 682  Solved: 364 Description 我们称一 ...

  8. POJ 3691 AC自动机上的dp

    题目大意: 给定一些不合理的DNA序列,再给一段较长的dna序列,问最少修改几次可以使序列中不存在任何不合理序列,不能找到修改方法输出-1 这里你修改某一个点的DNA可能会影响后面,我们不能单纯的找匹 ...

  9. 【BZOJ1030】[JSOI2007] 文本生成器(AC自动机上跑DP)

    点此看题面 大致题意: 给你\(N\)个字符串(只含大写字母),要你求出有多少个由\(M\)个大写字母构成的字符串含有这\(N\)个字符串中的至少一个. \(AC\)自动机 看到题目,应该比较容易想到 ...

随机推荐

  1. CodeForces 48C D - The Race (Fraction,数学)

    每个加油的站可以确定一个alpha的上下界,比如,第i次加油站a[i],前面加了i次油,a[i]*10≤ alpha*i <(a[i]+1)*10. 取最大的下界,取最小的上界,看看两者之间的满 ...

  2. CF Gym 100637G \#TheDress (水)

    题解:读懂题意按照题意模拟... 熟悉了一个库函数,strstr,memcpy #include<cstdio> #include<cstring> int main() { ...

  3. Spring boot 集成 Dubbo 快速搭建

    架构: 1.ZooKeeper:服务注册中心 2.api工程:提供对外暴露的服务API 3.provider:服务提供者 4.consumer:服务消费者 示例如下: (一)新建 Maven 项目 a ...

  4. python之函数的传参形参的第三种动态参数*args和**kwargs

    1. 位置/关键字传参的缺点 当给函数传入的参数数目不定时,之前的传参方式解决不了问题. def eat(food1,food2,food3): print(f'我请你吃:{food1},{food2 ...

  5. 剑指offer题目分类

    1. 链表 1. 从尾到头打印链表 2. 链表中倒数第k个结点 3. 反转链表 4. 合并两个排序的链表 5. 复杂链表的复制 6. 复杂链表的复制 7. 两个链表的第一个公共结点 8. 链表中环的入 ...

  6. c++作业:使用函数调用的方法,实现求两个整数中大的数的程序。

    #include <iostream> using namespace std; int main(){ //从键盘接收两个整数,保存在变量num1和num2中 cout<<& ...

  7. iOS 资源大全整理

    这是个精心编排的列表,它包含了优秀的 iOS 框架.库.教程.XCode 插件.组件等等. 这个列表分为以下几个部分:框架( Frameworks ).组件( Components ).测试( Tes ...

  8. Element表单验证(2)

    Element表单验证(2) 上篇讲的是async-validator的基本要素,那么,如何使用到Element中以及怎样优雅地使用,就在本篇. 上篇讲到async-validator由3大部分组成 ...

  9. deque 用法

    引用博客:https://blog.csdn.net/zyq522376829/article/details/46801973 下面是那位大佬写的的笔记整理~~~~ deque - 双向队列 1.构 ...

  10. 【mac】【php】mac php开机重启

    homebrew.mxcl.php71.plist   <?xml version="1.0" encoding="UTF-8"?> <!DO ...