Description
Solution
我们用
fn
表示
Concatenate(1...n)
,那么很容易推出
fi=fi−1∗10k+i
其中k是i的位数,会随着i变化。在不考虑变化的情况下,很容易推出矩阵:
[fii+11]∗⎡⎣⎢⎢⎢10k10011001⎤⎦⎥⎥⎥=[fi+1i+21]
之后,我们就可以枚举k,分段进行矩阵乘法即可。
注意初始矩阵为 [011]
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
struct matrix{
LL a[3][3];
matrix(){memset(a,0,sizeof a);}
}c,temp,I;
LL n,m,power[19];
matrix cheng(matrix x,matrix y){
matrix re;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
for(int k=0;k<3;k++){
(re.a[i][j]+=x.a[i][k]*y.a[k][j])%=m;
}
}
}
return re;
}
matrix pow(matrix x,LL y){
matrix re=I;
while(y){
if(y&1)re=cheng(re,x);
x=cheng(x,x);y>>=1;
}
return re;
}
int main(){
scanf("%lld%lld",&n,&m);
I.a[0][0]=I.a[1][1]=I.a[2][2]=1;
temp.a[0][1]=temp.a[0][2]=1;
c.a[1][0]=c.a[1][1]=c.a[2][1]=c.a[2][2]=1;
power[0]=1;
for(int i=1;i<=18;i++){
power[i]=power[i-1]*10;
}
for(int i=1;;i++){
c.a[0][0]=power[i]%m;
LL t=min(n,power[i]-1)-power[i-1]+1;
temp=cheng(temp,pow(c,t));
if(power[i]-1>=n)break;
}
printf("%lld\n",temp.a[0][0]);
return 0;
}