Description

我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串。例如当S=(22,333,0233)时,233是幸运数,2333、20233、3223不是幸运数。
    给定N和S,计算不大于N的幸运数个数。

Input

输入的第一行包含整数N。
    接下来一行一个整数M,表示S中元素的数量。
    接下来M行,每行一个数字串,表示S中的一个元素。

Output

输出一行一个整数,表示答案模109+7的值。

Sample Input

20
3
2
3
14

Sample Output

14

HINT

下表中l表示N的长度,L表示S中所有串长度之和。

1 < =l < =1200 , 1 < =M < =100 ,1 < =L < =1500


在AC自动机上跑DP。

设$\large f[0/1][i][j]$表示填到第i位,匹配到自动机上第j个节点, 是否有限制的方案数。

然后$\large f[0][i][j]$是可以转移到$\large f[0][i+1][nxt[j][k]]$的。

$\large f[1][i][j]$在k不等于这一位的时候可以转移到$\large f[0][i+1][nxt[j][k]]$,

在等于这一位的时候转移到$\large f[1][i+1][nxt[j][k]]$。

要特判一下匹配到根节点时,如果正在填第一位,只能从$\large [1, n[1]]$中选择数转移,和上面类似,

如果不是在填第1位,则可以直接转移到$\large f[0][...][...]$。

注意如果一个节点是一个单词的结尾就不转移,自动机上的表示要沿着fail指针传递。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
#define mod 1000000007
#define reg register
char n[];
int m; int cnt;
int nxt[][], end[], fail[];
int f[][][];//是否有限制,正在填第i个位置,匹配到第j个点.
int ans; inline void Ins(string s)
{
int now = ;
int len = s.length();
for (reg int i = ; i < len ; i ++)
now = nxt[now][s[i]-''] > ? nxt[now][s[i]-''] : (nxt[now][s[i]-''] = ++cnt);
end[now] = ;
} inline void AC_Match()
{
queue <int> q;
for (reg int i = ; i <= ; i ++)
if (nxt[][i]) q.push(nxt[][i]);
while(!q.empty())
{
int x = q.front();q.pop();
for (reg int i = ; i <= ; i ++)
{
if (nxt[x][i]) fail[nxt[x][i]] = nxt[fail[x]][i], q.push(nxt[x][i]), end[nxt[x][i]] |= end[nxt[fail[x]][i]];
else nxt[x][i] = nxt[fail[x]][i];
}
}
} signed main()
{
scanf("%s", n + );
scanf("%d", &m);
for (reg int i = ; i <= m ; i ++)
{
string x;
cin >> x;
Ins(x);
}
AC_Match();
int len = strlen(n + );
for (reg int i = ; i < len ; i ++)
{
for (reg int j = ; j <= cnt ; j ++)
{
if (f[][i][j]) {
for (reg int k = ; k <= ; k ++)
if (!end[nxt[j][k]]) (f[][i+][nxt[j][k]] += f[][i][j]) %= mod;
}
if (f[][i][j]) {
int up = n[i+] - '';
for (reg int k = ; k < up ; k ++)
if (!end[nxt[j][k]]) (f[][i+][nxt[j][k]] += f[][i][j]) %= mod;
if (!end[nxt[j][up]]) (f[][i+][nxt[j][up]] += f[][i][j]) %= mod;
}
if (j == )
{
if (i == ) {
int up = n[i+] - '';
for (reg int k = ; k < up ; k ++)
if (!end[nxt[j][k]]) (f[][i+][nxt[j][k]] += ) %= mod;
if (!end[nxt[j][up]]) (f[][i+][nxt[j][up]] += ) %= mod;
} else {
for (reg int k = ; k <= ; k ++)
if (!end[nxt[j][k]]) (f[][i+][nxt[j][k]] += ) %= mod;
}
}
}
}
for (reg int i = ; i <= cnt ; i ++)
(ans += (f[][len][i] + f[][len][i]) % mod) %= mod;
cout << ans << endl;
return ;
}

[BZOJ3550] [Sdoi2014]数数的更多相关文章

  1. 【BZOJ】【3530】【SDOI2014】数数

    AC自动机/数位DP orz zyf 好题啊= =同时加深了我对AC自动机(这个应该可以叫Trie图了吧……出边补全!)和数位DP的理解……不过不能自己写出来还真是弱…… /************* ...

  2. BZOJ3530: [Sdoi2014]数数

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 322  Solved: 188[Submit][Status] ...

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

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

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

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

  5. 「SDOI2014」数数 解题报告

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

  6. 3530: [Sdoi2014]数数

    3530: [Sdoi2014]数数 链接 分析: 对给定的串建立AC自动机,然后数位dp.数位dp的过程中,记录当前在AC自动机的哪个点上,保证不能走到出现了给定串的点. 代码: #include& ...

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

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

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

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

  9. [Sdoi2014]数数[数位dp+AC自动机]

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 834  Solved: 434[Submit][Status][ ...

  10. [bzoj3530][Sdoi2014]数数_AC自动机_数位dp

    数数 bzoj-3530 Sdoi-2014 题目大意:给你一个整数集合,求所有不超过n的正整数,是的它的十进制表示下不能再一段等于集合中的任意数. 注释:$1\le n \le 1200$,$1\l ...

随机推荐

  1. LOVE POWER html与javaScript

    1.纯HTML与javaScript编写的表白动态图 1.对于世界而言,你是一个人:但是对于某个人,你是他的整个世界. 2.不要为那些不愿在你身上花费时间的人而浪费你的时间. 3.我爱你,不是因为你是 ...

  2. Netty源码分析 (十一)----- 拆包器之LengthFieldBasedFrameDecoder

    本篇文章主要是介绍使用LengthFieldBasedFrameDecoder解码器自定义协议.通常,协议的格式如下: LengthFieldBasedFrameDecoder是netty解决拆包粘包 ...

  3. 品Spring:bean定义上梁山

    认真阅读,收获满满,向智慧又迈进一步... 技术不枯燥,先来点闲聊 先说点好事高兴一下.前段时间看新闻说,我国正式的空间站建设已在进行当中.下半年,长征五号B运载火箭将在海南文昌航天发射场择机将空间站 ...

  4. pathlib模块

    一.pathlib库官方定义 pathlib 是Python内置库,Python 文档给它的定义是 Object-oriented filesystem paths(面向对象的文件系统路径).path ...

  5. FTP无法登录问题-内有网盘福利

    http://dinghuqiang.blog.51cto.com/19871/701185/ 一顿操作猛如虎,还是没解决. 然后我想想,会不会是浏览器缓存问题? 换个火狐登录看看! 哇擦!看到报错了 ...

  6. 先森林后树木:Elasticsearch各版本升级核心内容必看

    在学习Elasticsearch 时候,因为各个版本的问题,搞不清,非常的头疼,官方也给出了各个版本更新的情况,不过是英文版本,版本更新信息又特别多,最近学习,看了很多资料,没有一个整理很清楚的,然后 ...

  7. Spring Boot 梳理 - 4个核心

    Spring Boot 魔法的核心:自动配置.起步依赖.命令行界面.Actuator 自动配置: 不用手动配置JdbcTemplate的Bean 不用手动配置DataSource的Bean Sprin ...

  8. 死磕 java线程系列之线程模型

    问题 (1)线程类型有哪些? (2)线程模型有哪些? (3)各语言使用的是哪种线程模型? 简介 在Java中,我们平时所说的并发编程.多线程.共享资源等概念都是与线程相关的,这里所说的线程实际上应该叫 ...

  9. abp(net core)+easyui+efcore实现仓储管理系统——EasyUI之货物管理三 (二十一)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...

  10. 使用 Jenkins 与 Sonar 集成对代码进行持续检测

    SonarQube 与 Jenkins 简介 SonarQube是 一个开源的代码质量分析平台,便于管理代码的质量,可检查出项目代码的漏洞和潜在的逻辑问题.同时,它提供了丰富的插件,支持多种语言的检测 ...