1009: [HNOI2008]GT exam
Time limit:1 Sec Memory limit:162 MB
submit:2230 solved:1364
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
The following:
First think of DP, and then see the data range, so naturally think of matrix multiplication.
For the transfer location, you can use KMP to speed up (it is said to be violent, but Lcomyn, Rivendell and Fye are all written by AC automata. )
I do not know why the matrix is wrong to write some sadness. Under the guidance of the Great God wrote a strange recursive matrix multiplication.
Code:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring
> #include <algorithm> using namespace std;
#define N-Char s[n];
int n,m,p,l,ans=0,next[n],a[n][n],b[n][n],f[n][n];
void Init () {L=strlen (s) +1;
for (int i=l-2; i>=0; i--) s[i+1]=s[i];
S[0]= ";
for (int i=2; i<l; i++) {int x=next[i-1];
while (x && s[i]!=s[x+1]) x=next[x];
if (s[i]==s[x+1]) next[i]=x+1;
} for (int i=0, i<l-1; i++) for (int j=0; j<=9; J + +) {int x=i;
while (x && j!=s[x+1]-' 0 ') x=next[x];
if (j==s[x+1]-' 0 ') f[i][x+1]++;
else f[i][0]++;
} memcpy (B,f,sizeof (f));
} void Jzc (int x) {if (x==1) return;
if (x>3) jzc (x>>1);
memset (A,0,sizeof (a)); for (int i=0, i<m; i++) for (int j=0; j<m; j + +) for (int k=0; k<m; k++) a[i][ J]= (A[i][j]+f[i][k]*f[k][j])
%p
memcpy (F,a,sizeof (a));
if (x&1) {memset (a,0,sizeof (a));
for (int i=0, i<m; i++) for (int j=0; j<m; j + +) for (int k=0; k<m; k++)
A[i][j]= (A[i][j]+f[i][k]*b[k][j])%p;
memcpy (F,a,sizeof (f));
}} int main () {scanf ("%d%d%d%s", &n,&m,&p,&s); Init ();
JZC (n);
for (int i=0; i<m; i++) ans= (ans+f[0][i])%p;
printf ("%d\n", ans);
return 0; }