题目大意:略

裸的AC自动机+数位DP吧...

定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量

然而会出现虚拟前导零,即前几位没有数字的情况,实际上是在0号节点原地打转,所以多加一维状态,再额外讨论第1位就行了

#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define NN 1210
#define MM 1510
#define ll long long
#define dd double
#define uint unsigned int
#define mod 1000000007
#define idx(X) (X-'0')
#define eps (1e-9)
using namespace std; int n,m,cte;
int head[NN];
struct Edge{int to,nxt;}edge[NN*];
void ae(int u,int v){
cte++;edge[cte].nxt=head[u];
head[u]=cte,edge[cte].to=v;
}
uint f[NN][MM][];
int ma[NN]; namespace AC{
int ch[NN][],fail[NN],tot,ed[NN];
void Build_Trie(char *str,int len)
{
int x=;
for(int i=;i<=len;i++){
if(!ch[x][idx(str[i])])
ch[x][idx(str[i])]=++tot;
x=ch[x][idx(str[i])];
}ed[x]=;
}
void Build_Fail()
{
queue<int>q;
for(int i=;i<=;i++)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty())
{
int x=q.front();q.pop();
ae(fail[x],x);
for(int i=;i<=;i++)
{
if(ch[x][i]){
fail[ch[x][i]]=ch[fail[x]][i];
q.push(ch[x][i]);
}else{
ch[x][i]=ch[fail[x]][i];
}
}
}
q.push();
while(!q.empty())
{
int x=q.front();q.pop();
for(int j=head[x];j;j=edge[j].nxt){
int v=edge[j].to;
ed[v]|=ed[x];
q.push(v);
}
}
}
void solve()
{
f[][][]++;
for(int j=;j<ma[];j++){
if(!ed[ch[][j]])
f[][ch[][j]][]++;}
if(!ed[ch[][ma[]]])
f[][ch[][ma[]]][]++;
for(int i=;i<n;i++)
{
f[i+][][]=;
int x=;
//nolimited
for(int j=;j<=;j++){
if(!ed[ch[x][j]])
(f[i+][ch[x][j]][]+=f[i][x][]+((j!=)?f[i][x][]:))%=mod;
}
//limited
for(int j=;j<ma[i+];j++)
if(!ed[ch[x][j]])
(f[i+][ch[x][j]][]+=f[i][x][])%=mod;
if(!ed[ch[x][ma[i+]]])
(f[i+][ch[x][ma[i+]]][]+=f[i][x][])%=mod;
for(x=;x<=tot;x++)
{
//nolimited
for(int j=;j<=;j++){
if(!ed[ch[x][j]])
(f[i+][ch[x][j]][]+=f[i][x][])%=mod;
}
//limited
for(int j=;j<ma[i+];j++)
if(!ed[ch[x][j]])
(f[i+][ch[x][j]][]+=f[i][x][])%=mod;
if(!ed[ch[x][ma[i+]]])
(f[i+][ch[x][ma[i+]]][]+=f[i][x][])%=mod;
//(f[i+1][ch[x][0]][2]+=f[i][x][2])%=mod;
}
}
uint ans=;
for(int x=;x<=tot;x++)
(ans+=f[n][x][]+f[n][x][])%=mod;
printf("%u\n",ans);
}
};
char str[NN]; int main()
{
//freopen("t1.in","r",stdin);
scanf("%s",str+);
n=strlen(str+);
for(int i=;i<=n;i++)
ma[i]=idx(str[i]);
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%s",str+);
int len=strlen(str+);
AC::Build_Trie(str,len);
}AC::Build_Fail();
AC::solve();
return ;
}

BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)的更多相关文章

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

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

  2. 【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp

    题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...

  3. HDU-4518 吉哥系列故事——最终数 AC自动机+数位DP

    题意:如果一个数中的某一段是长度大于2的菲波那契数,那么这个数就被定义为F数,前几个F数是13,21,34,55......将这些数字进行编号,a1 = 13, a2 = 21.现给定一个数n,输出和 ...

  4. zoj3494BCD Code(ac自动机+数位dp)

    l链接 这题想了好一会呢..刚开始想错了,以为用自动机预处理出k长度可以包含的合法的数的个数,然后再数位dp一下就行了,写到一半发现不对,还要处理当前走的时候是不是为合法的,这一点无法移到trie树上 ...

  5. BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]

    3530: [Sdoi2014]数数 题意:\(\le N\)的不含模式串的数字有多少个,\(n=|N| \le 1200\) 考虑数位DP 对于长度\(\le n\)的,普通套路DP\(g[i][j ...

  6. BZOJ3530[Sdoi2014]数数——AC自动机+数位DP

    题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...

  7. BZOJ3530:[SDOI2014]数数(AC自动机,数位DP)

    Description 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3 ...

  8. [SDOI2014]数数 --- AC自动机 + 数位DP

    [SDOI2014]数数 题目描述: 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串. 例如当S=(22,333,0233)时,233是幸运数,2333 ...

  9. BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)

    题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...

随机推荐

  1. DDD中Dto领域驱动设计概述,摘自《NET企业级应用架构设计》

  2. 第二章 Python数据类型详解

    基本概念 迭代(iteration):如果给定一个list或tuple,我们可以通过for循环来遍历,这种遍历我们称为迭代(iteration) 可变:value改变,id不变,可变类型是不可hash ...

  3. router+x

    vue-router官方的路由管理器 包含的功能: ——绑定方法进行跳转   路由嵌套   写的不一样搜索的路由路径也不一样   二级路由   设置默认路由   导航守卫: 用于强制跳转或者取消的方式 ...

  4. data is not None

    在读django的form源码: def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=Non ...

  5. 51nod-字符串连接

    输入n个字符串s[i],你要把他们按某个顺序连接起来,使得字典序最小. (1 <= n <= 100) (每个字符串长度 <= 100) (字符串只包含小写字母) Input 第一行 ...

  6. python中return和print的区别(详细)

    huskiesir最近在研究python哈,今天纠结一个问题,那就是return和print的区别,都是可以输出结果的,到底有啥区别呀?二话不多说,看下面的例子. #代码1: def break_wo ...

  7. oracle 的交并差函数,intersect;union;minus。

    创建表并添加数据: --创建TABLE_A create table TABLE_A ( A ), B ) ); --给TABLE_A添加数据 insert into TABLE_A values(' ...

  8. 题解 CF1051F 【The Shortest Statement】

    这道题思路比较有意思,第一次做完全没想到点子上... 看到题目第一反应是一道最短路裸题,但是数据范围1e5说明完全不可能. 这个时候可以观察到题目给出了一个很有意思的条件,就是说边最多比点多20. 这 ...

  9. 五大最佳开源java性能监控工具

    如果你正在寻找性能监控工具,不妨看看以下推荐的这五款开源工具,这些工具目前已经可以替代付费工具了,你可以看看是否是你的最佳选择.本文推荐的五款开源工具目前是开源社区中最受欢迎的. 1. Stagemo ...

  10. 洛谷 P2700 逐个击破

    P2700 逐个击破 题目背景 三大战役的平津战场上,傅作义集团在以北平.天津为中心,东起唐山西至张家口的铁路线上摆起子一字长蛇阵,并企图在溃败时从海上南逃或向西逃窜.为了就地歼敌不让其逃走,毛主席制 ...