Description
Ashen ready to enroll in the GT exam, the ticket number is n-digit x1x2....xn (0<=xi<=9), he does not want the ticket number on the appearance of unlucky numbers. His unlucky math a1a2 ... AM (0<=ai<=9) has M-bit, does not appear to refer to x1x2 ... The xn does not have exactly a paragraph equal to A1A2 ... Am. A1 and X1 can be 0 Input
The first line enters N,m,k. The next line is to enter the number of M bits. 100% data n<=10^9,m<=20,k<=1000 40% data n<=1000 10% data n<=6 Output
Ashen want to know how many kinds of numbers do not appear unlucky numbers, the result of output modulus K redundancy. Sample Input
4 3
111
Sample Output
81
HINT
Source
Set DP[I][J] The number of schemes that match the first number of numbers to the first J of an unlucky number.
Obviously the suffix of the first I number constitutes the first J unlucky number, and dp[i][j] to i+1 is equivalent to the suffix after the new addition of a character, can be associated with the AC automaton, but this only a string so KMP is enough.
Set A[K][J] to the number of scenarios where the K-bit is followed by one letter to J, so:
DP[I][J]=∑0<=K<=M−1DP[I−1][K]∗A[K][J] Dp[i][j]=\sum_{0
We found that the addition of a letter after K to J can be implemented with KMP.
The
equation is linear and can be optimized with matrices.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace
Std
typedef long Long LL;
const int SZ = 1000010;
const int INF = 1000000010;
int n,m,mod,nxt[233];
Char s[233];
void Getnxt (char s[]) {int L = strlen (s);
Nxt[0] = nxt[1] = 0;
for (int i = 1;i < L;i + +) {int j = nxt[i];
while (J && s[i]! = s[j]) j = nxt[j]; Nxt[i + 1] = s[i] = = S[j]?
j + 1:0;
}} struct matrix{int n,m,num[30][30];
Matrix (int a,int b): N (a), M (b) {memset (num,0,sizeof (num));}};
Matrix operator * (const matrix &a,const matrix &b) {matrix ans (A.N,B.M);
for (int i = 0;i < Ans.n;i + +) for (int j = 0;j < Ans.m;j + +) for (int k = 0;k < A.m;k + +)
ANS.NUM[I][J] = (Ans.num[i][j] + (LL) a.num[i][k] * b.num[k][j]% mod)% MoD;
return ans;
} Matrix KSM (Matrix A,int b) {matrix ans (A.N,A.M);
for (int i = 0;i < Ans.n;i + +) Ans.num[i][i] = 1;
while (b) {if (b & 1) ans = ans * A;
A = a * A;
b >>= 1;
} return ans;
} int main () {scanf ("%d%d%d%s", &n,&m,&mod,s);
GETNXT (s);
Matrix F (m,m);
for (int i = 0;i < M;i + +) {for (char j = ' 0 '; J <= ' 9 '; j + +) {int k = i;
while (k && s[k]! = j) k = Nxt[k];
if (s[k] = = j) k + +;
if (k! = m) f.num[i][k] + +;
}} Matrix fn = KSM (f,n), A (1,m);
A.num[0][0] = 1;
A = a * FN;
int ans = 0;
for (int i = 0;i < M;i + +) ans = (ans + a.num[0][i])% MoD;
printf ("%d\n", ans);
return 0;
}