"BZOJ1009" [HNOI2008]GT Exam description
Ashen ready to enroll in the GT exam, the ticket number is n-digit x1x2 .... Xn (0<=xi<=9), he does not want to appear on the ticket number of unlucky figures.
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 think
0
Input
The first line enters N,m,k. The next line is to enter the number of M bits. n<=10^9,m<=20,k<=1000
Output
Ashen want to know how many kinds of numbers do not appear unlucky numbers, the result of output modulus K redundancy.
Sample Input4 3 100
111Sample OutputBayi
the puzzle: Although the AC automata fail and KMP next only a little less, but why the feeling of AC automata than KMP good understanding 100 times times ~
Well, we'll still use KMP to find the next array, and then use F[i][j] to represent the I-bit number, the number of the I-bit matches the scheme when the first J bit of the template string
Then from 0.. 9 enumeration of the i+1 bit, after the i+1 bit is added to the position k, then there is f[i+1][k]+=f[i][j]
If the first bit matches successfully, at this time k=m, then f[i+1][m]+=f[i][j]
Obviously we can use the moment multiplication to optimize this DP process, we make x[i][j] to indicate that after 1 matches, from position I to the position of the scheme number of J. So for all of the above eligible (J,K), we make x[j][k]=1, the initial ans[0][0]=1. Then Ans*=x^n, the answer is ∑ans[0][0...m-1]
#include <cstdio> #include <cstring> #include <iostream>using namespace Std;int Next[25];char str[25] ; typedef struct MATRIX{INT v[25][25];} M M X,ans,emp;int n,m,mod,sum; M Mmul (M a,m b) {m c=emp;int i,j,k;for (i=0;i<=m;i++) for (j=0;j<=m;j++) for (k=0;k<=m;k++) c.v[i][j]= (c.v[i][j]+ A.V[I][K]*B.V[K][J])%mod;return C;} void pm (int y) {while (Y) {if (y&1) Ans=mmul (ans,x); X=mmul (x,x), Y>>=1;}} int main () {scanf ("%d%d%d%s", &n,&m,&mod,str), int i=0,j=-1,k;next[0]=-1;while (i<m-1) {if (j==-1| | STR[I]==STR[J]) next[++i]=++j;elsej=next[j];} for (i=0;i<m;i++) {for (j=0;j<=9;j++) {k=i;while (k!=-1&&str[k]-' 0 '!=j) k=next[k];x.v[i][k+1]++;}} X.V[M][M]=10,ANS.V[0][0]=1;PM (n); for (i=0;i<m;i++) sum= (Sum+ans.v[0][i])%mod;printf ("%d", sum); return 0;}
"BZOJ1009" [hnoi2008]gt exam next array + matrix multiplication