【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,输出和 ...
随机推荐
- SqlServer中怎么删除重复的记录(表中没有id)
SqlServer中怎么删除重复的记录(表中没有id) 其实我在别的网址也查到过删除重复的记录,不知道我是我SqlServer2012版本太低还是啥原因 delete from scwhere (c# ...
- 第33题:LeetCode255 Verify Preorder Sequence in Binary Search Tree 验证先序遍历是否符合二叉搜索树
题目 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 考点 1.BST 二叉搜索树 2.递归 思路 1.后序 ...
- Exception occurred during processing request: The given object has a null identifier: com.zsn.crm.Model.SaleVisit; nested exception is org.hibernate.TransientObjectException: The given object has a nu
edit.jsp页面没有加入隐藏字段 id ,导致模型驱动封装时缺少id ,,调用update更新数据库时出错!
- 精读《12 个评估 JS 库你需要关心的事》
1 引言 作者给出了从 12 个角度全面分析 JS 库的可用性,分别是: 特性. 稳定性. 性能. 包生态. 社区. 学习曲线. 文档. 工具. 发展历史. 团队. 兼容性. 趋势. 下面总结一下作者 ...
- SpringCloud框架搭建+实际例子+讲解+系列五
(4)服务消费者,面向前端或者用户的服务 本模块涉及到很多知识点:比如Swagger的应用,SpringCloud断路器的使用,服务API的检查.token的校验,feign消费者的使用.大致代码框架 ...
- C语言数组篇(二)指针数组和数组指针
数组指针 和 指针数组 这两个名词可以说是经常搞混了 数组指针--> 数组的指针 就是前面讲的 指向数组a的指针p; 指针数组--&g ...
- C# 控件置于最顶层、最底层、隐藏、显示
控件置于最顶层.最底层 pictureBox1.BringToFront();//将控件放置所有控件最前端 pictureBox1.SendToBack();//将控件放置所有控件最底端 控件隐藏.显 ...
- Flume使用(案例分析)
Flume官方文档 Usage: bin/flume-ng <command> [options]... commands: help display this help text age ...
- Win7更换锁屏和开机画面
技术交流群:233513714 每次开机被Windows千年不变的开机画面和锁屏画面丑到的小伙伴们可以看过来,通过简单的几步就可以改掉系统默认的开机画面. 1.首先Windows+r键输入regedi ...
- mysql 中的基本用法,以及日期的转换
1.mysql int(10) int 类型长度4个字节,大约表示2^32数字,10代表的是显示长度,一般和FILLZERO约束一起使用,如果没有达到该长度,填充02-->000000002 m ...