There are b blocks of digits. Each one consisting of the same n digits, which are given to you in the input. Wet Shark must choose exactly one digit from each block and concatenate all of those digits together to form one large integer. For example, if he chooses digit 1 from the first block and digit 2 from the second block, he gets the integer 12.
Wet Shark then takes this number modulo x. Please, tell him how many ways he can choose one digit from each block so that he gets exactly k as the final result. As this number may be too large, PRint it modulo 109?+?7.
Note, that the number of ways to choose some digit in the block is equal to the number of it's occurrences. For example, there are 3 ways to choose digit 5 from block 3 5 6 7 8 9 5 1 1 1 1 5.
InputThe first line of the input contains four space-separated integers, n, b, k and x (2?≤?n?≤?50?000,?1?≤?b?≤?109,?0?≤?k?<?x?≤?100,?x?≥?2) — the number of digits in one block, the number of blocks, interesting remainder modulo x and modulo x itself.
The next line contains n space separated integers ai (1?≤?ai?≤?9), that give the digits contained in each block.
OutputPrint the number of ways to pick exactly one digit from each blocks, such that the resulting integer equals k modulo x.
Examplesinput12 1 5 103 5 6 7 8 9 5 1 1 1 1 5output3input3 2 1 26 2 2output0input3 2 1 23 1 2output6NoteIn the second sample possible integers are 22, 26, 62 and 66. None of them gives the remainder 1 modulo 2.
In the third sample integers 11, 13, 21, 23, 31 and 33 have remainder 1 modulo 2. There is exactly one way to obtain each of these integers, so the total answer is 6.
題意:
給你n個數(shù),這n個數(shù)的大小都在1~9之間,有b塊集合,每個集合內(nèi)都有這n個數(shù),你要從每個集合中取出一個數(shù),并把它們依次拼接起來合并成一個大的整數(shù),問最后這個整數(shù)%x得到k的方案數(shù)有多少。
題解:
我們可以先把1~9在n出現(xiàn)的次數(shù)用occ[i]存下來 ,然后用dp[i][j]表示取前i個數(shù),最終模x后為j的方案數(shù),那么容易得到dp[0][0]=1,dp[i][j]=sum{dp[i-1][a]*occ[d] }(其中(a*10+d)%x==j),但因為b太大,所以我們考慮用矩陣快速冪優(yōu)化.
由于對于指定的膜數(shù)x,我們可以遍歷每個余數(shù)i和j,再遍歷k(k為1-9的數(shù)),如果(i*10+k)%x==j,那么矩陣data[i][j]+=occ[k].
然后對構(gòu)造的這個矩陣進(jìn)行快速冪運(yùn)算即可。
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<queue>#include<stack>using namespace std;#define rep(i,a,n) for (int i=a;i<n;i++)#define per(i,a,n) for (int i=n-1;i>=a;i--)#define pb push_back#define fi first#define se secondtypedef vector<int> VI;typedef long long ll;typedef pair<int,int> PII;const int inf=0x3fffffff;const ll mod=1000000007;const int maxn=100+10;struct matrix{ int n; ll data[maxn][maxn]; matrix(int tn=0){ n=tn; rep(i,0,n) rep(j,0,n) data[i][j]=0; } void init(){ rep(i,0,n) data[i][i]=1; }};matrix Operator *(matrix a,matrix b){ matrix c(a.n); int n=a.n; rep(i,0,n) rep(j,0,n) rep(k,0,n) c.data[i][j]=(c.data[i][j]+a.data[i][k]*b.data[k][j]%mod)%mod; return c;}matrix func(matrix a,int b){ matrix t(a.n),ans(a.n); ans.init(); t=a; while(b) { if(b&1) ans=ans*t; t=t*t; b>>=1; } return ans;}int a[15];int main(){ int n,b,kk,x; scanf("%d%d%d%d",&n,&b,&kk,&x); rep(i,1,n+1) { int p; scanf("%d",&p); a[p]++; } matrix tmp(x); rep(i,0,x) rep(j,0,x) rep(k,1,10) if((i*10+k)%x==j) tmp.data[i][j]+=a[k]; // matrix ans(x); ans=func(tmp,b); cout << ans.data[0][kk] << endl; return 0;}
新聞熱點
疑難解答