bzoj1009矩阵快速面+kmp
其实kmp真的很次要,求长度为20的kmp感觉真的有点杀鸡用牛刀
这题思路相当明确:一看题就是数位dp,一看n的大小就是矩阵
矩阵的构造用m*m比较方便,本来想写1*m的矩阵乘m*m的,但是感觉想起来太麻烦就偷懒,没想到1A了
log的速度的确可以,87ms贼快,好久没见这么短的运行时间了
1 #include <cstdio> 2 int n,m,mod,k; 3 char ch; 4 int a[100],ne[100]; 5 int ans[100][100],t[100][100],zy[100][100]; 6 void mul(bool b) 7 { 8 for(int i=0;i<m;i++) 9 for(int j=0;j<m;j++) 10 for(k=0,t[i][j]=0;k<m;k++) 11 t[i][j]=(t[i][j]+(b?ans[i][k]:zy[i][k])*zy[k][j])%mod; 12 for(int i=0;i<m;i++) 13 for(int j=0;j<m;j++) 14 if(b) ans[i][j]=t[i][j]; 15 else zy[i][j]=t[i][j]; 16 if(b) n--;else n/=2; 17 } 18 int main() 19 { 20 scanf("%d%d%d",&n,&m,&mod); 21 for(ch=getchar();ch<'0' || ch>'9';ch=getchar()); 22 for(int i=1;i<=m;i++,ch=getchar()) 23 a[i]=ch-'0'; 24 for(int i=2;i<=m;i++) 25 { 26 int k=ne[i-1]; 27 while(k && (a[k+1]!=a[i])) k=ne[k]; 28 ne[i]=k+(a[k+1]==a[i]); 29 } 30 for(int i=0;i<m;i++) 31 for(int j=0;j<=9;j++) 32 { 33 int k=i; 34 while(k && a[k+1]!=j) k=ne[k]; 35 k+=(a[k+1]==j); 36 if(k!=m) zy[k][i]++; 37 } 38 for(int i=0;i<m;i++) 39 ans[i][i]=1; 40 while(n) 41 mul(n&1); 42 int sum=0; 43 for(int i=0;i<m;i++) 44 sum=(sum+ans[i][0])%mod; 45 printf("%d",sum); 46 return 0; 47 }