1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #define ll long long 6 ll b[20],x[3][3],y[3][3],n,a[20],ans,ans1,m; 7 void cheng(ll q[3][3],ll q1[3][3]) 8 { 9 ll q2[3][3]; 10 memset(q2,0,sizeof(q2)); 11 for(int i=0;i<3;i++) 12 for(int j=0;j<3;j++) 13 for(int k=0;k<3;k++) 14 q2[i][j]=(q2[i][j]+(q[i][k]*q1[k][j])%m)%m; 15 for(int i=0;i<3;i++) 16 for(int j=0;j<3;j++) 17 q[i][j]=q2[i][j]; 18 return; 19 } 20 int main() 21 { 22 scanf("%lld%lld",&n,&m); 23 b[0]=1; 24 for(int i=1;i<=18;i++) 25 { 26 b[i]=(b[i-1]*10); 27 if(n>=b[i]) 28 a[0]=i; 29 } 30 a[0]++; 31 if(n<10) 32 a[1]=n; 33 else 34 a[1]=9; 35 for(int i=2;i<a[0];i++) 36 a[i]=a[i-1]*10; 37 if(n>=10) 38 a[a[0]]=n-b[a[0]-1]+1; 39 for(int i=1;i<=a[0];i++) 40 { 41 memset(x,0,sizeof(x)); 42 x[2][1]=x[2][0]=x[1][1]=x[1][0]=x[0][0]=1; 43 memset(y,0,sizeof(y)); 44 x[2][2]=b[i]%m; 45 y[0][0]=y[1][1]=y[2][2]=1; 46 ll k=a[i]; 47 for(;k;) 48 { 49 if(k%2) 50 cheng(y,x); 51 cheng(x,x); 52 k/=2; 53 } 54 ans=(y[2][0]+(y[2][1]*ans1)%m+(y[2][2]*ans)%m)%m; 55 ans1=(y[1][0]+(ans1*y[1][1])%m)%m; 56 } 57 printf("%lld\n",ans); 58 return 0; 59 }
这是个矩阵乘法 对相同的位数构建一个矩阵。