神奇,矩阵乘法23333333333333333
递推式是很简单的(连我这种不会DP的人都写出来了。)
需要求出的是转移矩阵(还是叫系数矩阵的),也是最这个东西用快速幂。
这个东西的i,j大概就表示从i到j的方案数,那么原始的状态肯定是f[0]=1;对应的矩阵也就是[1,0,0,0,0,0,0,,,,,,]
貌似为了方便??!!这个矩阵貌似可以转化成f[i][i]=1的矩阵。。。所以。。(太BT了,,,还是我太垃圾)
还有最后的答案输出,想了想data[?][kk],?是什么也不好,一开始是0位,答案求的也是从0到b位的,所以就data[0][kk]吧。。(简直乱搞)
1 #include<bits/stdc++.h> 2 #define inf 0x7fffffff 3 #define LL long long 4 #define N 100005 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 const int mod=1e9+7; 14 int a[15]; 15 struct maxtri{ 16 int n; 17 LL data[110][110]; 18 maxtri(int tn=0) 19 { 20 n=tn; 21 for (int i=0; i<n; i++) 22 for (int j=0; j<n; j++) 23 data[i][j]=0; 24 } 25 void init() 26 { 27 for (int i=0; i<n; i++) data[i][i]=1; 28 } 29 }; 30 maxtri operator *(maxtri a, maxtri b) 31 { 32 maxtri c(a.n); 33 int n=a.n; 34 for (int i=0; i<n; i++) 35 for (int j=0; j<n; j++) 36 for (int k=0; k<n; k++) 37 c.data[i][j]=(c.data[i][j]+a.data[i][k]*b.data[k][j]%mod)%mod; 38 return c; 39 } 40 maxtri ksm(maxtri a, int b) 41 { 42 maxtri t(a.n),ans(a.n); 43 ans.init(); t=a; 44 while (b) 45 { 46 if (b&1) ans=ans*t; 47 t=t*t; 48 b>>=1; 49 } 50 return ans; 51 } 52 int main() 53 { 54 int n=ra(),b=ra(),kk=ra(),x=ra(); 55 for (int i=1; i<=n; i++) 56 a[ra()]++; 57 maxtri tmp(x); 58 for (int i=0; i<x; i++) 59 for (int j=0; j<x; j++) 60 for (int k=1; k<10; k++) 61 if ((i*10+k)%x==j) tmp.data[i][j]+=a[k]; 62 maxtri ans(x); 63 ans=ksm(tmp,b); 64 cout<<ans.data[0][kk]; 65 return 0; 66 }