【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp
题目描述
我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串。例如当S=(22,333,0233)时,233是幸运数,2333、20233、3223不是幸运数。
给定N和S,计算不大于N的幸运数个数。
输入
输入的第一行包含整数N。
接下来一行一个整数M,表示S中元素的数量。
接下来M行,每行一个数字串,表示S中的一个元素。
输出
输出一行一个整数,表示答案模109+7的值。
样例输入
20
3
2
3
14
样例输出
14
题解
AC自动机+数位dp
同学的某道考试题的加强版。。。
由于给定的串多且复杂,要求不能匹配到这些串,所以可以对这些串建立Trie图。
然后设$f[i][j]$表示从$j$开始走$i$个节点,不触碰到危险节点(即得到的是非幸运数)的方案数。
那么如果$j$是危险节点则方案数为0,否则枚举$j$走出去的第一步,用$f[i-1][next[j][k]]$更新$f[i][j]$。
考虑数位dp的过程:
首先处理出位数不满$n$位的数的个数:枚举位数和最高位(非0),然后方案数即为$f[i][next[1][j]]$。
然后考虑位数满$n$位的数的个数:
考虑从高到底的每一位:从0到当前位-1是满的(即后面的数恰好从0到10^{位数}),因此可以直接从$f$中取出。再考虑当前位不满的情况,此时转化为了子问题,按照同样的方法处理即可。
注意最高位是不能包含前导0的,而确定最高位以后其余的位是可以包含前导0的。
时间复杂度$O(10nL)$
细节贼多。。。代码凑合着看吧。。。
#include <queue>
#include <cstdio>
#include <cstring>
#define N 1510
#define mod 1000000007
using namespace std;
queue<int> q;
int next[N][10] , tot = 1 , fail[N] , tag[N] , f[N][N];
char s[N] , w[N];
void build()
{
int x , i;
for(i = 0 ; i < 10 ; i ++ ) next[0][i] = 1;
q.push(1);
while(!q.empty())
{
x = q.front() , q.pop() , tag[x] |= tag[fail[x]];
for(i = 0 ; i < 10 ; i ++ )
{
if(next[x][i]) fail[next[x][i]] = next[fail[x]][i] , q.push(next[x][i]);
else next[x][i] = next[fail[x]][i];
}
}
}
int main()
{
int n , m , i , j , k , t , flag , ans = 0;
scanf("%s%d" , s , &m) , n = strlen(s);
for(i = 1 ; i <= m ; i ++ )
{
scanf("%s" , w);
for(j = 0 , t = 1 ; w[j] ; j ++ )
{
if(!next[t][w[j] ^ '0']) next[t][w[j] ^ '0'] = ++tot;
t = next[t][w[j] ^ '0'];
}
tag[t] = 1;
}
build();
for(i = 1 ; i <= tot ; i ++ ) f[1][i] = !tag[i];
for(i = 2 ; i <= n ; i ++ )
for(j = 1 ; j <= tot ; j ++ )
if(!tag[j])
for(k = 0 ; k < 10 ; k ++ )
f[i][j] = (f[i][j] + f[i - 1][next[j][k]]) % mod;
for(i = 1 ; i < n ; i ++ )
for(j = 1 ; j < 10 ; j ++ )
ans = (ans + f[i][next[1][j]]) % mod;
for(i = 0 , t = flag = 1 ; i < n ; i ++ )
{
for(j = flag ; j < (s[i] ^ '0') ; j ++ ) ans = (ans + f[n - i][next[t][j]]) % mod;
t = next[t][s[i] ^ '0'];
if(tag[t]) break;
flag = 0;
}
if(!tag[t]) ans = (ans + 1) % mod;
printf("%d\n" , ans);
return 0;
}
【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp的更多相关文章
- 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 682 Solved: 364 Description 我们称一 ...
- 【JZOJ3624】【SDOI2014】数数(count) AC自动机+数位dp
题面 100 容易想到使用AC自动机来处理禁忌子串的问题: 然后在自动机上数位dp,具体是: \(f_{i,j,0/1}\)表示填了\(i\)位,当前在自动机的第\(j\)个结点上,\(0\)表示当前 ...
- BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)
题目大意:略 裸的AC自动机+数位DP吧... 定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量 然而会出现虚拟前导零,即前几位没有数字的情况, ...
- BZOJ3530:[SDOI2014]数数(AC自动机,数位DP)
Description 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3 ...
- BZOJ3530[Sdoi2014]数数——AC自动机+数位DP
题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...
- BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
3530: [Sdoi2014]数数 题意:\(\le N\)的不含模式串的数字有多少个,\(n=|N| \le 1200\) 考虑数位DP 对于长度\(\le n\)的,普通套路DP\(g[i][j ...
- [SDOI2014]数数 --- AC自动机 + 数位DP
[SDOI2014]数数 题目描述: 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串. 例如当S=(22,333,0233)时,233是幸运数,2333 ...
- P3311 [SDOI2014]数数 AC自动机+数位DP
题意 给定一个正整数N和n个模式串,问不大于N的数字中有多少个不包含任意模式串,输出对\(1e^9+7\)取模后的答案. 解题思路 把所有模式串都加入AC自动机,然后跑数位DP就好了.需要注意的是,这 ...
- HDU-4518 吉哥系列故事——最终数 AC自动机+数位DP
题意:如果一个数中的某一段是长度大于2的菲波那契数,那么这个数就被定义为F数,前几个F数是13,21,34,55......将这些数字进行编号,a1 = 13, a2 = 21.现给定一个数n,输出和 ...
随机推荐
- 刚学不久的python,自己稍微加工了一点,影响不大,因为博主很懒,所以格式什么的,就没有太在意了!
本人初学python,之前因为有接触过其他语言,但是并没有接触的太深,出于对一个hacker的向往,学习一下Linux和python再说,当然,也是为了高工资啦,啊哈哈哈! 一开始就是一个蛮有意思的小 ...
- LeetCode46. Permutations
Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3] O ...
- LeetCode804. Unique Morse Code Words
题目 国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: "a" 对应 ".-", "b" 对应 ...
- SAP BI 常用TCODE
S.No Tcode Description 1 RSA1 Administrator Work Bench 2 RSA11 Calling up AWB with the IC tree 3 RSA ...
- dts--framework(二)
Framwork下个文件中包含的函数 packet.py LayersTypes = { ', 'arp', 'lldp'], # ipv4_ext_unknown, ipv6_ext_unknown ...
- Lucene简单总结
Lucene API Document Document:文档对象,是一条原始数据 文档编号 文档内容 1 谷歌地图之父跳槽FaceBook 2 谷歌地图之父加盟FaceBook 3 谷歌地图创始人拉 ...
- [Luogu3806]点分治
询问树上是否存在距离为k[i]的点对 直接点分治把所有距离预处理出来,然后O(1)回答即可 Code #include <cstdio> #include <algorithm> ...
- 一个比较良好的flask项目结构
一个比较良好的flask项目结构 project/ app/ # 整个程序的包目录 static/ # 静态资源文件 js/ ...
- spark练习--统计xxx大学的各个少数名族的情况
最近,有一份数据,是关于学校的数据,这个里面有所有学生的信息,今天闲来没事,我就想用spark的方式来读取文件,并且来统计这个学校的各个民族的情况,以前我用hadoop中mapReduce来计算,不得 ...
- 15.3,redis持久化RDB与AOF
redis持久化 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. RDB持久化 ...