bzoj1009矩阵快速面+kmp

其实kmp真的很次要,求长度为20的kmp感觉真的有点杀鸡用牛刀

这题思路相当明确:一看题就是数位dp,一看n的大小就是矩阵

矩阵的构造用m*m比较方便,本来想写1*m的矩阵乘m*m的,但是感觉想起来太麻烦就偷懒,没想到1A了

log的速度的确可以,87ms贼快,好久没见这么短的运行时间了

 #include <cstdio>
int n,m,mod,k;
char ch;
int a[],ne[];
int ans[][],t[][],zy[][];
void mul(bool b)
{
for(int i=;i<m;i++)
for(int j=;j<m;j++)
for(k=,t[i][j]=;k<m;k++)
t[i][j]=(t[i][j]+(b?ans[i][k]:zy[i][k])*zy[k][j])%mod;
for(int i=;i<m;i++)
for(int j=;j<m;j++)
if(b) ans[i][j]=t[i][j];
else zy[i][j]=t[i][j];
if(b) n--;else n/=;
}
int main()
{
scanf("%d%d%d",&n,&m,&mod);
for(ch=getchar();ch<'' || ch>'';ch=getchar());
for(int i=;i<=m;i++,ch=getchar())
a[i]=ch-'';
for(int i=;i<=m;i++)
{
int k=ne[i-];
while(k && (a[k+]!=a[i])) k=ne[k];
ne[i]=k+(a[k+]==a[i]);
}
for(int i=;i<m;i++)
for(int j=;j<=;j++)
{
int k=i;
while(k && a[k+]!=j) k=ne[k];
k+=(a[k+]==j);
if(k!=m) zy[k][i]++;
}
for(int i=;i<m;i++)
ans[i][i]=;
while(n)
mul(n&);
int sum=;
for(int i=;i<m;i++)
sum=(sum+ans[i][])%mod;
printf("%d",sum);
return ;
}
上一篇:虚方法virtual详解


下一篇:js- 引用和复制(传值和传址)