分段递推+矩阵乘法
根据模运算的分配律,i表示连接到第几个数,有递推式:f[i]= f[i-1]*(10^log(i))+i mod M
构造矩阵进行加速
{f[i-1],i-1,1}
*
{ 10^log(i) ,, 0 ,, 0 }
{ 1 ,,,,,,,,,,,,,,,,,, 1 ,, 0 }
{ 0 ,,,,,,,,,,,,,,,,,, 1 ,, 1 }
(空格没法对齐,强行用逗号对齐)
#include<cstdio>
#include<cstring>
#define ll long long
ll m;
struct matrix
{
ll mat[4][4];
matrix()
{
memset(mat,0,sizeof(mat));
}
void unit()
{
for(int i = 1; i <= 3; i++)
mat[i][i]=1;
}
matrix operator *(matrix a)
{
matrix ans;
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++)
for(int k = 1; k <= 3; k++)
ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*a.mat[k][j])%m;
return ans;
}
}temp;
matrix fpow(matrix base, ll b)
{
matrix r;
r.unit();
while(b)
{
if(b&1)
r=r*base;
base=base*base;
b>>=1;
}
return r;
}
int main()
{
ll n, p=10;
scanf("%lld%lld",&n,&m);
matrix f;
f.mat[1][3]=1;
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= i; j++)
temp.mat[i][j]=1;
while(n>=p)
{
temp.mat[1][1]=p%m;
f=f*fpow(temp,p/10*9);
p=p*10;
}
temp.mat[1][1]=p%m;
f=f*fpow(temp,n-p/10+1);
printf("%lld\n",f.mat[1][1]);
return 0;
}