您的位置:首页 > 其它

bzoj 3530 [Sdoi2014]数数

2017-05-25 10:26 253 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: