解法:记ai=concatnate(1..i),则ai=ai−1⋅10Ω(i)+i,其中Ω(i)为i的位数.
这是一个线性递推关系,Ω(i)最大不超过18,那么枚举Ω(i),构造矩阵做若干次矩阵乘法即可.
AC code:
#include <cstdio>
typedef long long ll;
ll n,m,f;
ll A[4][4],M[4][4];
void qpow(ll A[4][4],ll x){
if(x==1){
for(ll i=1;i<=3;i++)
for(ll j=1;j<=3;j++)
M[i][j]=A[i][j];
return ;
}
qpow(A,x>>1);
ll B[4][4]={{0}};
for(ll i=1;i<=3;i++)
for(ll j=1;j<=3;j++)
for(ll k=1;k<=3;k++)
B[i][j]=(B[i][j]+A[i][k]*A[k][j])%m;
for(ll i=1;i<=3;i++){
for(ll j=1;j<=3;j++){
A[i][j]=B[i][j];B[i][j]=0;
}
}
if(x&1){
for(ll i=1;i<=3;i++)
for(ll j=1;j<=3;j++)
for(ll k=1;k<=3;k++)
B[i][j]=(B[i][j]+A[i][k]*M[k][j])%m;
for(ll i=1;i<=3;i++)
for(ll j=1;j<=3;j++)
A[i][j]=B[i][j];
}
}
int main(){
scanf("%lld%lld",&n,&m);
for(ll i=1;i<10;i++){
f=(f*10+i)%m;
if(i==n){
printf("%lld\n",f);
return 0;
}
}
for(ll i=99;;i=i*10+9){
A[3][3]=(i+1)%m;
A[1][1]=A[2][1]=A[2][2]=A[3][1]=A[3][2]=1;
if(n<=i){
qpow(A,n-i/10);
printf("%lld\n",(A[3][1]+A[3][2]*(i/10%m)+A[3][3]*f)%m);
break;
}
qpow(A,i-i/10);
f=(A[3][1]+A[3][2]*(i/10%m)+A[3][3]*f)%m;
}
return 0;
}