分析
令
Fn=[fn(第n项)fn+1(第n+1项)Sn(前n项和)]\begin{array}{ll}
&F_{n}=
&\begin{bmatrix}
f_{n}(第n项) & f_{n+1}(第n+1项) & S_{n}(前n项和)\\
\end{bmatrix}
\end{array}Fn=[fn(第n项)fn+1(第n+1项)Sn(前n项和)]
则
Fn+1=[fn+1fn+2Sn+1]\begin{array}{ll}
&F_{n+1}=
&\begin{bmatrix}
f_{n+1} & f_{n+2} & S_{n+1}\\
\end{bmatrix}
\end{array}Fn+1=[fn+1fn+2Sn+1]
由这两个矩阵可以计算出所要进行运算的矩阵A:
A=[010111001]\begin{array}{ll} &A= &\begin{bmatrix} 0 & 1& 0\\ 1 & 1& 1\\ 0 & 0& 1\\ \end{bmatrix} \end{array}A=⎣⎡010110011⎦⎤
由此可计算出矩阵的和:Fn+1=F1∗An−1 由此可计算出矩阵的和:F_{n+1}=F_{1}*A^{n-1} 由此可计算出矩阵的和:Fn+1=F1∗An−1
所以只用乘上A矩阵的(n-1)次方
输入样例
25000 100000
输出样例
84375
(计算第25000项的斐波那契数列的总和对100000取模后的结果)
C++ 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int m,n;
LL a[3][3]={ //预定义A矩阵
{0,1,0},
{1,1,1},
{0,0,1}
};
void mul1(LL c[3],LL a[3],LL b[3][3]) //计算F矩阵乘A矩阵
{
LL temp[3]={0};
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
temp[i]=(temp[i]+a[j]*b[j][i])%m;
memcpy(c,temp,sizeof temp);
}
void mul2(LL c[][3],LL a[][3],LL b[][3]) //计算A矩阵乘A矩阵
{
LL temp[3][3]={0};
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
temp[i][j]=(temp[i][j]+a[i][k]*b[k][j])%m;
memcpy(c,temp,sizeof temp);
}
int main()
{
LL f[3]={1,1,1};
cin>>n>>m;
n--; //计算第n项的和只需要乘n-1次A矩阵,所以n--
while(n)
{
if(n&1) mul1(f,f,a);
mul2(a,a,a);
n>>=1;
}
cout<<f[2];
return 0;
}