5 10
数列的递推公式为: F [ 0 ] = 1 , F [ 1 ] = 1 , F [ n ] = F [ n − 1 ] + F [ n − 2 ] ( n > = 3 ) F[0]=1,F[1]=1,F[n]=F[n-1]+F[n-2](n>=3) F[0]=1,F[1]=1,F[n]=F[n−1]+F[n−2](n>=3)
用矩阵可以这么表示:
{ F n F n − 1 } \left\{ \begin{matrix} F_n\\ F_{n-1}\\ \end{matrix} \right\} {FnFn−1}
= { F n − 1 + F n − 2 F n − 1 } = \left\{ \begin{matrix} F_{n-1}+F_{n-2}\\ F_{n-1}\\ \end{matrix} \right\} ={Fn−1+Fn−2Fn−1}
= { 1 ∗ F n − 1 + 1 ∗ F n − 2 1 ∗ F n − 1 + 0 ∗ F n − 2 } = \left\{ \begin{matrix} 1*F_{n-1}+1*F_{n-2}\\ 1*F_{n-1}+0*F_{n-2}\\ \end{matrix} \right\} ={1∗Fn−1+1∗Fn−21∗Fn−1+0∗Fn−2}
= { 11 10 } ∗ { F n − 1 F n − 2 } = \left\{ \begin{matrix} 1 1\\ 1 0\\ \end{matrix} \right\}* \left\{ \begin{matrix} F_{n-1}\\ F_{n-2}\\ \end{matrix} \right\} ={1110}∗{Fn−1Fn−2}
= { 11 10 } n − 1 ∗ { F 1 F 0 } = \left\{ \begin{matrix} 1 1\\ 1 0\\ \end{matrix} \right\}^{n-1}* \left\{ \begin{matrix} F_1\\ F_0\\ \end{matrix} \right\} ={1110}n−1∗{F1F0}
= { 11 10 } n − 1 ∗ { 1 0 } = \left\{ \begin{matrix} 1 1\\ 1 0\\ \end{matrix} \right\}^{n-1}* \left\{ \begin{matrix} 1\\ 0\\ \end{matrix} \right\} ={1110}n−1∗{10}
于是我们采用矩阵乘法 O ( 2 3 l o g N ) O(2^3logN) O(23logN) 顺利解决此题
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fd(i,a,b) for(int i=a;i>=b;--i)
#define ll long long
using namespace std;
const int N=2;
ll n,P;
struct matrix
{
ll a[N][N];
}A,Ans;
matrix mul(matrix A,matrix B)
{
matrix C;
memset(C.a,0,sizeof(C.a));
fo(k,0,1)
fo(i,0,1) if(A.a[i][k])
fo(j,0,1) if(B.a[k][j])
C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j]%P)%P;
return C;
}
matrix ksm(matrix A,ll k)
{
matrix S;
fo(i,0,1) fo(j,0,1) S.a[i][j]=(i==j);
for(;k;A=mul(A,A),k>>=1)
if(k&1) S=mul(S,A);
return S;
}
int main()
{
scanf("%lld%lld",&n,&P);
A.a[0][0]=A.a[0][1]=A.a[1][0]=1,A.a[1][1]=0;
Ans=ksm(A,n-1);
printf("%lld",(Ans.a[0][0]+Ans.a[0][1])%P);
}