Math Homework
Description
Suddenly found that matrix multiplication is not well-written ...
(This ZZ overloaded operator does not play return debug full 30min)
Find a very simple recursive type:
F[n]=f[n−1]∗ (Floor (LG10) +1) +n f[n]=f[n-1]* (Floor (LG10) +1) +n
So it is obvious that this floor (LG10) +1 floor (LG10) +1 will be the same for a long time, so this value can be divided into blocks.
Then consider a block of values by floor (LG10) floor (LG10), as in shape 10. 999,100 ... 999, the same without repeated calculations.
Consider using matrix multiplication to optimize this process:
Make floor (LG10) +1=x floor (LG10) +1=x
So for each piece you can construct the following transfer matrices:
X 0 0
1 1 0
0 1 1
The direct chunking matrix can be quickly idempotent.
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <
Algorithm> using namespace std;
typedef long Long LL;
const int n=5;
ll N,MD;
struct Matrix {ll a[n][n],lena,lenb;
void E () {for (int i=0;i<lena;i++) a[i][i]=1;
} matrix (int _a,int _b,ll f=-1) {lena=_a;
Lenb=_b;
memset (A,0,sizeof (a));
if (f!=-1) {e ();
A[0][0]=f;
A[1][0]=a[2][1]=1;
}} Matrix operator * (Matrix O) {matrix res (LENA,O.LENB);
for (int i=0;i<lena;i++) for (int. j=0;j<o.lenb;j++) for (int k=0;k<lenb;k++)
(RES.A[I][J]+=A[I][K]*O.A[K][J]%MD)%=MD;
return res;
} void Out () {for (int i=0;i<lena;i++,puts (""))) for (int j=0;j<lenb;j++)
printf ("%lld", A[i][j]);
}
}; Inline Matrix Qpow (MatRix A,ll b) {matrix ret (3,3);
RET.E ();
while (b) {if (b&1) ret=ret*a;
A=a*a;
b>>=1;
} return ret;
} int main () {scanf ("%lld%lld", &N,&MD);
Matrix ans (3,3);
ANS.E ();
ll I;
for (i=10;i<=n;i=i*10) Ans=ans*qpow (Matrix (3,3,I%MD), I-I/10);
Ans=ans*qpow (Matrix (3,3,I%MD), n-i/10+1);
printf ("%lld\n", (Ans.a[1][0]+ans.a[2][0])%MD);
return 0; }