Description
给定$n$个数和$b$个盒子,放一些数到盒子中,使得盒子不为空。每个盒子中的数是一样的,一个数可以被放到多个盒子中。
从每个盒子中取一个数,组成一个$b$位数,如果这个数$mod;k=x$,则这是一种合法的方案。求方案数$mod;10^9+7$。
Input
第一行为$4$个数$n,b,x,k$。
Output
一行,表示方案数$mod 10^9+7$。
Sample Input
3 2 1 2
3 1 2
Sample Output
6
HINT
$2;leq;n;leq;50000,1;leq;b;leq;10^9,0;leq;k;leq;100, x;geq;2,1;leq;a_i;leq;9$
Solution
显然序列中有用的条件仅有每个数出现的次数,记为$t[;]$。
$f[i][j]$表示前$i$位数$mod;k$的值为$j$的方案数。
$f[i+1][(j; imes;10+l)mod;n]=f[i][j]; imes;t[l]$。
矩乘优化$DP$就能过了。
1 #include<cmath> 2 #include<ctime> 3 #include<queue> 4 #include<stack> 5 #include<cstdio> 6 #include<vector> 7 #include<cstring> 8 #include<cstdlib> 9 #include<iostream> 10 #include<algorithm> 11 #define lld I64d 12 #define K 15 13 #define N 105 14 #define M 1000000007 15 using namespace std; 16 typedef long long ll; 17 struct matrix{ 18 ll a[N][N];int n,m; 19 }a,b; 20 ll t[K]; 21 int n,m,k,x; 22 inline matrix mult(matrix a,matrix b){ 23 matrix c;c.n=a.n;c.m=b.m; 24 for(int i=0;i<c.n;++i) 25 for(int j=0;j<c.m;++j){ 26 c.a[i][j]=0; 27 for(int k=0;k<a.m;++k) 28 c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%M; 29 } 30 return c; 31 } 32 inline matrix po(matrix a,int k){ 33 matrix c;c.n=a.n;c.m=a.m; 34 for(int i=0;i<a.n;++i) 35 for(int j=0;j<b.n;++j) 36 if(i!=j) c.a[i][j]=0; 37 else c.a[i][j]=1; 38 while(k){ 39 if(k&1) c=mult(c,a); 40 a=mult(a,a);k>>=1; 41 } 42 return c; 43 } 44 inline void init(){ 45 scanf("%d%d%d%d",&n,&m,&x,&k); 46 for(int i=1,j;i<=n;++i){ 47 scanf("%d",&j);++t[j]; 48 } 49 a.n=k;a.m=1; 50 for(int i=1;i<=9;++i) 51 a.a[i%k][0]+=t[i]; 52 b.n=b.m=k; 53 for(int i=0,l;i<k;++i){ 54 for(int j=1;j<=9;++j){ 55 l=(i*10+j)%k; 56 b.a[l][i]+=t[j]; 57 } 58 } 59 matrix c=mult(po(b,m-1),a); 60 printf("%lld ",c.a[x][0]); 61 } 62 int main(){ 63 freopen("blocks.in","r",stdin); 64 freopen("blocks.out","w",stdout); 65 init(); 66 fclose(stdin); 67 fclose(stdout); 68 return 0; 69 }