Wet Shark and Blocks
题意
有
b
b
组数,每组都有相同的 个数,现要从每组数中选择一个数,联起来构成一个大数,使其对
x
x
取膜后的值为 ,问有多少种方案?最终答案对
109+7
10
9
+
7
取膜
题解
dp[i][j]
d
p
[
i
]
[
j
]
: 第
i
i
组数对 取膜后的值为
j
j
的方案数
: 数字
a
a
的数量
可得转移方程
由于 b b <script type="math/tex" id="MathJax-Element-52">b</script> 太大,用矩阵快速幂加速求解
代码
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int x,num[20];
struct Matrix
{
int n,m,d[110][110];
Matrix (int N,int M)
{
n = N, m = M;
memset(d,0,sizeof(d));
}
friend Matrix operator * (const Matrix &a,const Matrix &b)
{
Matrix c(a.n,b.m);
for (int i=0;i<a.n;i++)
for (int j=0;j<b.m;j++)
{
long long tmp = 0;
for (int k=0;k<a.m;k++)
{
tmp += (long long)a.d[i][k]*b.d[k][j] % mod;
tmp = tmp % mod;
}
c.d[i][j] = tmp % mod;
}
return c;
}
};
int main()
{
int n,a,b,k;
while (scanf("%d %d %d %d",&n,&b,&k,&x)!=EOF)
{
memset(num,0,sizeof(num));
for (int i=0;i<n;i++)
{
scanf("%d",&a);
num[a]++;
}
Matrix A(1,x);
Matrix B(x,x);
A.d[0][0] = 1;
for (int j=0;j<x;j++)
for (int t=1;t<=9;t++)
B.d[j][(j*10+t)%x] = (B.d[j][(j*10+t)%x]+num[t]) % mod;
while (b)
{
if (b & 1) A = A*B;
B = B*B;
b >>= 1;
}
printf("%d\n",A.d[0][k]);
}
return 0;
}