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

解题思路:

很明显是个数位Dp,相当于n位的不要62,由于不要62的字符个数是可以枚举的,这个不可以。

设计一个状态dp[i][j][onlim(0/1)][zero(0/1)]来表示字符到了 i 位,Trie图上到了 j 号节点,是否压了上线,是否有前导零。

转移则是寻找Trie图上一个子节点,如果不代表字符的结束,那么进一位,判断是否压上界,是否为零即可。

注意子节点为root时不向下转移Trie图(即失配)

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
const lnt mod=(lnt)(1e9+);
struct trnt{
int ch[];
int fl;
bool fin;
}tr[];
class queue{
public:
queue(void){h=,t=;return ;}
int nxt(int x){if(x+==)return ;return x+;}
int front(void){return line[h];}
void pop(void){h=nxt(h);return ;}
void push(int x){t=nxt(t);line[t]=x;return ;}
bool empty(void){return nxt(t)==h;}
private:
int h,t,line[];
}Q;
int siz;
int n,m;
int l;
char tmp[];
int num[];
lnt dp[][][][];
void Insert(char *a)
{
int root=;
int len=strlen(a+);
for(int i=;i<=len;i++)
{
int c=a[i]-'';
if(!tr[root].ch[c])
tr[root].ch[c]=++siz;
root=tr[root].ch[c];
}
tr[root].fin=true;
return ;
}
void Build(void)
{
int root=;
for(int i=;i<;i++)
if(tr[root].ch[i])
Q.push(tr[root].ch[i]);
while(!Q.empty())
{
root=Q.front();
Q.pop();
tr[root].fin|=tr[tr[root].fl].fin;
for(int i=;i<;i++)
if(tr[root].ch[i])
{
tr[tr[root].ch[i]].fl=tr[tr[root].fl].ch[i];
Q.push(tr[root].ch[i]);
}else
tr[root].ch[i]=tr[tr[root].fl].ch[i];
}
return ;
}
int main()
{
scanf("%s",tmp+);
l=strlen(tmp+);
for(int i=;i<=l;i++)
num[i]=tmp[i]-'';
scanf("%d",&m);
for(int i=;i<=m;i++)
{
scanf("%s",tmp+);
Insert(tmp);
}
Build();
dp[][][][]=;
for(int i=;i<=l;i++)
{
for(int j=;j<=siz;j++)
{
for(int onlim=;onlim<;onlim++)
{
for(int zero=;zero<;zero++)
{
if(!dp[i-][j][onlim][zero])
continue;
int lim=onlim*num[i]+(-onlim)*;
for(int c=;c<=lim;c++)
{
if(tr[tr[j].ch[c]].fin)
continue;
int nwlim=onlim&&(c==lim);
int nwzro=zero&&(!c);
int nwplc=(-nwzro)*tr[j].ch[c];
dp[i][nwplc][nwlim][nwzro]=(dp[i][nwplc][nwlim][nwzro]+dp[i-][j][onlim][zero])%mod;
}
}
}
}
}
lnt ans=;
for(int i=;i<=siz;i++)
ans=(ans+dp[l][i][][]+dp[l][i][][])%mod;
printf("%lld\n",(ans+mod)%mod);
return ;
}

BZOJ3530: [Sdoi2014]数数(Trie图,数位Dp)的更多相关文章

  1. BZOJ_3209_花神的数论题_组合数+数位DP

    BZOJ_3209_花神的数论题_组合数+数位DP Description 背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 描述 话说花神这天又 ...

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

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

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

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

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

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

  5. uva11361 特殊数的数量(数位dp)

    题目传送门 题目大意:给你一个n-m的区间,问你这个闭区间内的特殊数有几个,特殊数的要求是 数的本身 和 各位数字之和  mod k 等于0. 思路:刚接触数位dp,看了网上的题解,说用dp[i][j ...

  6. 【ECNU77】位与数对个数(数位DP)

    点此看题面 大致题意: 求\(\sum_{x=0}^{a-1}\sum_{y=0}^{b-1}[(x\&y)<k]\). 数位\(DP\) 显然数位\(DP\)吧. 我们设\(f_{n, ...

  7. 【Dream Counting, 2006 Dec-数数的梦】数位dp

    题意:给定两个数,问区间[A,B]中0~9分别出现了多少次.A,B<=10^18 题解:应该是最裸的数位dp吧..一开始没有记忆化tle了TAT 我们可以求出区间[0,B]的,再减去区间[0,A ...

  8. bzoj1833: [ZJOI2010]count 数字计数&&USACO37 Cow Queueing 数数的梦(数位DP)

    难受啊,怎么又遇到我不会的题了(捂脸) 如题,这是一道数位DP,随便找了个博客居然就是我们大YZ的……果然nb,然后就是改改模版++注释就好的了,直接看注释吧,就是用1~B - 1~A-1而已,枚举全 ...

  9. P4317 花神的数论题 动态规划?数位DP

    思路:数位$DP$ 提交:5次(其实之前A过,但是调了调当初的程序.本次是2次AC的) 题解: 我们分别求出$sum(x)=i$,对于一个$i$,有几个$x$,然后我们就可以快速幂解决. 至于求个数用 ...

随机推荐

  1. poj3169 差分约束系统

    题意: 从1到n,n个数,从左向右依次排列. 给定两种形式的约束条件: 1.xi与yi的最大距离为dk 2.xi与yi的最小距离为dk 问满足这些限定条件的情况下,数1和n的最大距离是多少?(若约束条 ...

  2. Docker Network Configuration 高级网络配置

    Network Configuration TL;DR When Docker starts, it creates a virtual interface named docker0 on the ...

  3. vim 插件之 surround.vim

    surround.vim-这个插件主要是用来插入一些特殊符号的(成对出现) 下载地址 http://www.vim.org/scripts/script.php?script_id=1697 http ...

  4. Pycharm 的安装

    一. Windows 安装 汉化 破解补丁激活 下载 `https://pan.baidu.com/s/1qjI9uHaw0x374rwu6H8djA` 并将 JetbrainsCrack-2.8-r ...

  5. HTTP 与 HTTPS

    https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密. 防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名. 另外是加密,加密需要一个密钥交换算法,双方 ...

  6. AIX 压缩与归档

    .tar.Z 格式 压缩:  compress filename.tar 解压:  zcat filename.tar.Z           tar -xvf -   .tar.gz 格式 压缩:t ...

  7. 测试理论--web测试方法总结

    一.输入框 1.字符型输入框: (1)字符型输入框:英文全角.英文半角.数字.空或者空格.特殊字符“~!@#¥%……&*?[]{}”特别要注意单引号和&符号.禁止直接输入特殊字符时,使 ...

  8. Python入门:全站url爬取

    <p>作为一个安全测试人员,面对一个大型网站的时候,手工测试很有可能测试不全,这时候就非常需要一个通用型的网站扫描器.当然能直接扫出漏洞的工具也有很多,但这样你只能算是一个工具使用者,对于 ...

  9. webp学习http://isux.tencent.com/introduction-of-webp.html

    http://isux.tencent.com/introduction-of-webp.html http://jingyan.baidu.com/article/2d5afd699cd7de85a ...

  10. TCP/IP协议族-----20、远程登录:TELNET与SSH