3530: [Sdoi2014]数数

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

 
AC自动机好容易出DP啊。。。。
f[i][j][1 or 0]表示前i位,转移到j节点时的方案数,1表示前i位与n的前i位相同,0表示不同。。
然后分开求一下就好了。。。。
不过不知道为什么我的代码不对。。。
zyf—zyf:
  1 #include<cstdio>
  2 
  3 #include<cstdlib>
  4 
  5 #include<cmath>
  6 
  7 #include<cstring>
  8 
  9 #include<algorithm>
 10 
 11 #include<iostream>
 12 
 13 #include<vector>
 14 
 15 #include<map>
 16 
 17 #include<set>
 18 
 19 #include<queue>
 20 
 21 #include<string>
 22 
 23 #define inf 1000000000
 24 
 25 #define maxn 2000+5
 26 
 27 #define maxm 20000000+5
 28 
 29 #define eps 1e-10
 30 
 31 #define ll long long
 32 
 33 #define pa pair<int,int>
 34 
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36 
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38 
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40 
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42 
 43 #define mod 1000000007
 44 
 45 using namespace std;
 46 
 47 inline int read()
 48 
 49 {
 50 
 51     int x=0,f=1;char ch=getchar();
 52 
 53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 54 
 55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 56 
 57     return x*f;
 58 
 59 }
 60 int n,m,cnt,a[maxn],go[maxn],t[maxn][26],f[maxn][maxn][2];
 61 char s[maxn];
 62 bool v[maxn];
 63 queue<int>q;
 64 inline void add()
 65 {
 66     scanf("%s",s+1);int len=strlen(s+1),now=1;
 67     for1(i,len)
 68         {
 69             int x=s[i]-'0';
 70             if(!t[now][x])t[now][x]=++cnt;
 71             now=t[now][x];
 72         }
 73     v[now]=1;
 74 }
 75 void bfs()
 76 {
 77     q.push(1);
 78     while(!q.empty())
 79     {
 80         int x=q.front(),y,j;v[x]|=v[go[x]];q.pop();
 81         for0(i,9)
 82         {
 83             j=go[x];
 84             while(j&&!t[j][i])j=go[j];
 85             if(t[x][i])
 86             {
 87                 go[y=t[x][i]]=j?t[j][i]:1;
 88                 q.push(y);
 89             }else t[x][i]=j?t[j][i]:1;
 90         }
 91     }
 92 }
 93 
 94 int main()
 95 
 96 {
 97 
 98     //freopen("input.txt","r",stdin);
 99 
100     //freopen("output.txt","w",stdout);
101     scanf("%s",s+1);n=strlen(s+1);
102     for1(i,n)a[i]=s[i]-'0';
103 
104     m=read();cnt=1;
105     for0(i,9)t[1][i]=++cnt;
106     while(m--)add();
107     bfs();
108     for1(i,a[1])if(!v[t[1][i]])f[1][t[1][i]][i==a[1]]=1;
109     for1(i,n-1)
110      for1(j,cnt)
111       {
112          for0(k,a[i+1])if(!v[t[j][k]])(f[i+1][t[j][k]][k==a[i+1]]+=f[i][j][1])%=mod;
113          for0(k,9)if(!v[t[j][k]])(f[i+1][t[j][k]][0]+=f[i][j][0])%=mod;
114       }
115     int ans=0;
116     for1(i,cnt)(ans+=f[n][i][0])%=mod,(ans+=f[n][i][1])%=mod;
117     memset(f,0,sizeof(f));
118     for1(i,9)if(!v[t[1][i]])f[1][t[1][i]][0]=1;
119     for1(i,n-2)
120       for1(j,cnt)
121         for0(k,9)
122          if(!v[t[j][k]])(f[i+1][t[j][k]][0]+=f[i][j][0])%=mod;
123     for1(i,n-1)
124       for1(j,cnt)
125         (ans+=f[i][j][0])%=mod;
126     printf("%d\n",ans);
127 
128     return 0;
129 
130 }
View Code

我的:

  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<algorithm>
  7 #include<string>
  8 #include<map>
  9 #include<queue>
 10 #include<vector>
 11 #include<set>
 12 #define inf 1000000000
 13 #define maxn 120000+5
 14 #define bit 1200
 15 #define maxm 100+5
 16 #define eps 1e-10
 17 #define ll long long
 18 #define mod 1000000007
 19 #define for0(i,n) for(int i=0;i<=(n);i++)
 20 #define for1(i,n) for(int i=1;i<=(n);i++)
 21 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 22 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 23 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 24 using namespace std;
 25 int read(){
 26     int x=0,f=1;char ch=getchar();
 27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 29     return x*f;
 30 }
 31 int n,m,cnt=1,t[maxn][10],danger[maxn],point[maxn],f[bit][maxm][1],a[bit];
 32 char ch[maxn];
 33 queue<int> q;
 34 void insert(){
 35     int len=strlen(ch),now=1;
 36     for0(i,len-1){
 37         int x=ch[i]-'0';
 38         if(!t[now][x])t[now][x]=++cnt;
 39         now=t[now][x];
 40     }
 41     danger[now]=1;
 42 }
 43 void build(){
 44     q.push(1);
 45     while(!q.empty()){
 46         int x=q.front();q.pop();danger[x]|=danger[point[x]];
 47         for0(i,9){
 48             int tmp=point[x];
 49             while(tmp&&!t[tmp][i])tmp=point[tmp];
 50             if(t[x][i]){
 51                 point[t[x][i]]=tmp?t[tmp][i]:1;
 52                 q.push(t[x][i]);            
 53             }
 54             else t[x][i]=tmp?t[tmp][i]:1;
 55         }
 56     } 
 57 }
 58 int main(){
 59     //freopen("input.txt","r",stdin);
 60     //freopen("output.txt","w",stdout);
 61     scanf("%s",ch);n=strlen(ch);
 62     for0(i,n-1)
 63         a[i+1]=ch[i]-'0';
 64     m=read();
 65     for0(i,9)t[1][i]=++cnt;
 66     for1(i,m){
 67         scanf("%s",ch);
 68         insert();
 69     }
 70     build();
 71     for1(i,a[1])
 72         if(!danger[t[1][i]])
 73             f[1][t[1][i]][a[1]==i]=1;
 74     for(int i=2;i<=n;i++)
 75         for1(j,cnt){
 76             for0(k,a[i])
 77                 if(!danger[t[j][k]])
 78                     f[i][t[j][k]][a[i]==k]=(f[i][t[j][k]][a[i]==k]+f[i-1][j][1])%mod;
 79             for0(k,9)
 80                 if(!danger[t[j][k]])
 81                     f[i][t[j][k]][0]=(f[i][t[j][k]][0]+f[i-1][j][0])%mod;
 82         }
 83     int ans=0;
 84     for1(i,cnt)
 85         ans=(ans+f[n][i][0]+f[n][i][1])%mod;
 86     memset(f,0,sizeof(f));
 87     for1(i,9)
 88         if(!danger[t[1][i]])
 89             f[1][t[1][i]][0]=1;
 90     for(int i=2;i<n;i++)
 91         for1(j,cnt)
 92             for0(k,9)
 93                 if(!danger[t[j][k]])
 94                     f[i][t[j][k]][0]=(f[i][t[j][k]][0]+f[i-1][j][0])%mod;
 95     for1(i,n-1)
 96         for1(j,cnt)
 97             ans=(ans+f[i][j][0])%mod;
 98     printf("%d\n",ans);
 99     return 0;
100 }
View Code

 

posted @ 2016-06-16 18:21  HTWX  阅读(122)  评论(0编辑  收藏  举报