分析
令
F
n
=
[
f
n
(
第
n
项
)
f
n
+
1
(
第
n
+
1
项
)
S
n
(
前
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项和)]
则
F
n
+
1
=
[
f
n
+
1
f
n
+
2
S
n
+
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 = [ 0 1 0 1 1 1 0 0 1 ] \begin{array}{ll} &A= &\begin{bmatrix} 0 & 1& 0\\ 1 & 1& 1\\ 0 & 0& 1\\ \end{bmatrix} \end{array} A=⎣⎡010110011⎦⎤
由
此
可
计
算
出
矩
阵
的
和
:
F
n
+
1
=
F
1
∗
A
n
−
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;
}