在求fibonacci数列的第n项时。如果n很大,可以使用矩阵快速幂的方法。
1.通过递推公式得到矩阵。
a
n
=
a
n
−
1
+
a
n
−
2
;
得
到
2
个
向
量
,
v
1
=
[
a
n
,
a
n
−
1
]
,
a_n=a_{n-1}+a_{n-2};得到2个向量,v_1=[a_n,a_{n-1}],
an=an−1+an−2;得到2个向量,v1=[an,an−1],
v
2
=
[
a
n
−
1
,
a
n
−
2
]
,
矩
阵
快
速
幂
求
数
列
第
n
项
不
再
赘
v_2=[a_{n-1},a_{n-2}],矩阵快速幂求数列第n项不再赘
v2=[an−1,an−2],矩阵快速幂求数列第n项不再赘
述
。
设
矩
阵
为
A
,
则
[
a
n
,
a
n
−
1
]
=
A
n
−
2
[
a
2
,
a
1
]
述。设矩阵为A,则[a_n,a_{n-1}]=A^{n-2}[a_2,a_1]
述。设矩阵为A,则[an,an−1]=An−2[a2,a1]
2.必要的介绍已经完成。进入本篇所讨论的题目。
现在给定一个数列的第一项和第二项:1 1
数列递推式为:
a
n
=
a
n
−
1
+
a
n
−
2
+
n
4
a_n=a_{n-1}+a_{n-2}+n^4
an=an−1+an−2+n4
求第20220206130000项模上1e9+7后的结果。
本递推公式涉及到n的高次方。
不
妨
设
向
量
为
v
1
=
[
a
n
,
a
n
−
1
,
n
4
,
n
3
,
n
2
,
n
,
1
]
,
v
2
不妨设向量为v_{1}=[a_n,a_{n-1},n^4,n^3,n^2,n,1],v_{2}
不妨设向量为v1=[an,an−1,n4,n3,n2,n,1],v2
=
[
a
n
−
1
,
a
n
−
2
,
(
n
−
1
)
4
,
(
n
−
1
)
3
,
(
n
−
1
)
2
,
(
n
−
1
)
,
1
]
=[a_{n-1},a_{n-2},(n-1)^4,(n-1)^3,(n-1)^2,(n-1),1]
=[an−1,an−2,(n−1)4,(n−1)3,(n−1)2,(n−1),1]
这里后面的n,n-1的次方为什么来的。本人数学基础太差。不由而知。还请各位数学大佬指教。
之后,是求解矩阵的过程。矩阵的每一个纵列是二项式展开的系数。具体由读者自己思考。这里给出矩阵。
1
1
0
0
0
0
0
1
0
0
0
0
0
0
1
0
1
0
0
0
0
4
0
4
1
0
0
0
6
0
6
3
1
0
0
4
0
4
3
2
1
0
1
0
1
1
1
1
1
\begin{matrix} 1&1&0&0&0&0&0\\ 1&0&0&0&0&0&0\\ 1&0&1&0&0&0&0\\ 4&0&4&1&0&0&0\\ 6&0&6&3&1&0&0\\ 4&0&4&3&2&1&0\\ 1&0&1&1&1&1&1\\ \end{matrix}
1114641100000000146410001331000012100000110000001
之后就是矩阵快速幂的过程。不再赘述。直接上代码。
public class SolutionE {
static int mod= 1000000007;
public static void main(String[] args) {
long times=20220206129997l;
long[][] matrix={{1,1,0,0,0,0,0},{1,0,0,0,0,0,0},{1,0,1,0,0,0,0},{4,0,4,1,0,0,0},{6,0,6,3,1,0,0},{4,0,4,3,2,1,0},{1,0,1,1,1,1,1}};
long[][] res={{1,1,16,8,4,2,1}};
long[][] resultMatrix=matrix;
while (times!=0){
if(times%2==1){resultMatrix=mutiply(resultMatrix,matrix);}
times/=2;
matrix=mutiply(matrix,matrix);
}
res=mutiply(res,resultMatrix);
System.out.println(res[0][0]);
}
private static long[][] mutiply(long[][] matrix1, long[][] matrix2) {
long[][] result=new long[Math.min(matrix1.length,matrix2.length)][Math.min(matrix1[0].length,matrix2[0].length)];
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[0].length; j++) {
for (int k = 0; k < Math.max(result.length,result[0].length); k++) {
result[i][j]+=((matrix1[i][k]*matrix2[k][j])%mod);
result[i][j]%=mod;
}
}
}
return result;
}
}