bzoj 3530 [Sdoi2014]数数

来源:互联网 发布:伯俊软件 编辑:程序博客网 时间:2024/05/22 12:35

3530: [Sdoi2014]数数

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 530  Solved: 298
[Submit][Status][Discuss]

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

Source

Round 1 day 1




【分析】

Orz 阿当学长  传送门




【代码】

#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define ll long long#define p 1000000007#define M(a) memset(a,0,sizeof a)#define fo(i,j,k) for(int i=j;i<=k;i++)using namespace std;const int mxn=1505;queue <int> q;char s[mxn];int m,T,num,ans;int n[mxn];int dp[mxn][mxn][2];struct node {int son[10],fail,cnt;} a[mxn];inline void trie(){scanf("%s",s+1);    int x=0,len=strlen(s+1);    fo(i,1,len)    {        int t=s[i]-'0';        if(!a[x].son[t])          a[x].son[t]=(++num);        x=a[x].son[t];    }    a[x].cnt=1;}inline void build(){    fo(i,0,9)      if(a[0].son[i]) q.push(a[0].son[i]);    while(!q.empty())    {        int x=q.front();q.pop();        int fail=a[x].fail;        fo(i,0,9)        {            int y=a[x].son[i];            if(y) a[y].fail=a[fail].son[i],q.push(y);            else a[x].son[i]=a[fail].son[i];        }        a[x].cnt|=a[fail].cnt;    }}inline void dynamic(int len){M(dp);fo(i,1,9)  if(!a[a[0].son[i]].cnt)    dp[1][a[0].son[i]][0]++;fo(i,1,len-2)  fo(j,0,num)    fo(k,0,9) if(!a[a[j].son[k]].cnt)      (dp[i+1][a[j].son[k]][0]+=dp[i][j][0])%=p;fo(i,1,len-1) fo(j,0,num) (ans+=dp[i][j][0])%=p;M(dp);fo(i,1,n[1])  if(!a[a[0].son[i]].cnt)    dp[1][a[0].son[i]][i==n[1]]++;fo(i,1,len-1)  fo(j,0,num)    fo(k,0,9) if(!a[a[j].son[k]].cnt)    {    (dp[i+1][a[j].son[k]][0]+=dp[i][j][0])%=p;    if(k<n[i+1]) (dp[i+1][a[j].son[k]][0]+=dp[i][j][1])%=p;    else if(k==n[i+1]) (dp[i+1][a[j].son[k]][1]+=dp[i][j][1])%=p;}fo(j,0,num) (ans+=dp[len][j][0])%=p,(ans+=dp[len][j][1])%=p;}int main(){scanf("%s",s+1);int len=strlen(s+1);fo(i,1,len) n[i]=s[i]-'0';scanf("%d",&m);fo(i,1,m) trie();build();dynamic(len);printf("%d\n",ans);return 0;}


原创粉丝点击