这种题我都WA了一个小时我是不是没救了
首先写出递推式$f[i]=f[i-1] \times 10^{len_{i}} + i $
然后按照\(len_{i}\)分层用矩阵乘法优化即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cassert>
using namespace std;
long long n;
long long ans=0;
int mm;
struct Matrix{
long long z[4][4];
Matrix(){
memset(z,0,sizeof(z));
}
void Clr(){
memset(z,0,sizeof(z));
}
void MakeE(){
memset(z,0,sizeof(z));
z[1][1]=z[2][2]=z[3][3]=1;
}
};
Matrix Multiply(Matrix A,Matrix B){
Matrix C;
for(int i=1;i<=3;++i){
for(int j=1;j<=3;++j){
for(int k=1;k<=3;++k){
C.z[i][j]=(C.z[i][j]+A.z[i][k]*B.z[k][j])%mm;
}
}
}
return C;
}
Matrix Ksm(Matrix a,long long p){
Matrix ret;
ret.MakeE();
for(;p;p>>=1,a=Multiply(a,a)){
if(p&1)ret=Multiply(ret,a);
}
return ret;
}
int main(){
scanf("%lld%d",&n,&mm);
int len=0;
long long x=n;
while(x){
x/=10;++len;
}
long long now=1;
for(int i=1;i<=len;++i){
long long k;
if(i==len){
k=n-now+1;
}else{
k=now*10-now;
}
Matrix a;
a.z[1][1]=(now*10)%mm;
a.z[1][2]=1;
a.z[1][3]=1;
a.z[2][2]=1;
a.z[2][3]=1;
a.z[3][3]=1;
Matrix ret=Ksm(a,k);
ans=(ans*ret.z[1][1]%mm+(now-1+mm)%mm*ret.z[1][2]%mm+ret.z[1][3])%mm;
now=now*10;
}
cout<<ans<<endl;
return 0;
}