题意:求Fibonacci数列的第n项,并对结果取模,即求
其中
这里由于n的值很大,故我们不能使用递推的方法求得第n项,于是我们考虑更快的矩阵快速幂
设 表示一个
的矩阵
,我们希望依据
推出
。
尝试推倒一个base矩阵,使 ,即
于是我们便可以推倒出这样一个式子:
定义 那么则有
这个矩阵的第一行第一列元素,也就是
的第一行第一列元素。
另外,当 的时候可以直接输出1,不需要执行矩阵快速幂。
AC代码如下:
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
int n;
int mod;
struct matrix{ //定义矩阵
int a[3][3];
matrix() {memset(a,0,sizeof a);}
matrix operator*(const matrix &b) const
{
matrix res;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
res.a[i][j]=(res.a[i][j]+a[i][k]*b.a[k][j])%mod;
return res;
}
}ans,base;
void init()//初始化ans矩阵
{
base.a[1][1]=base.a[1][2]=base.a[2][1]=1;
ans.a[1][1]=ans.a[1][2]=1;
}
void qpow(int b)//用快速幂的方式优化矩阵乘法
{
while(b)
{
if(b&1)
ans=ans*base;
base=base*base;
b>>=1;
}
}
signed main()
{
cin>>n>>mod;
if(n<=2)//小于2直接输出1
cout<<1%mod<<endl;
init();
qpow(n-2);
cout<<ans.a[1][1]%mod<<endl;//输出答案,第一行第一列的元素
return 0;
}