Description
斐波那契数列即 1, 1, 2, 3, 5...,F(n) = F(n−1) + F(n−2) 。求斐波那契数列第 n 项
Input
每组数据给出 1 ≤ n ≤ 10^9 。
Output
斐波那契数列第 n 项 对 10^9 + 7 取模
Sample Input
1
2
20
100000000
Sample Output
1
1
6765
908460138
该题属于矩阵快速幂的经典应用
首先我们需要一些线性代数的知识
利用上图公式,我们可以对某一矩阵进行降幂操作
如:
![]()
这样我们实际上就只需计算矩阵A的n-1次方就可以得到Fn了,此时答案就是矩阵A的n-1次方的第一行数相加
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> #define int long long using namespace std; const int mod = 1e9 + 7; struct Node { int mat[2][2]; Node(){} Node(int a_, int b_, int c_, int d_) { mat[0][0] = a_; mat[0][1] = b_; mat[1][0] = c_; mat[1][1] = d_; } Node operator*(const Node &y) { // TODO: 矩阵乘法,注意取模 int a1=mat[0][0],a2=mat[0][1],b1=mat[1][0],b2=mat[1][1]; Node node((a1*y.mat[0][0]+a2*y.mat[1][0])%mod, (a1*y.mat[0][1]+a2*y.mat[1][1])%mod, (b1*y.mat[0][0]+b2*y.mat[1][0])%mod, (b1*y.mat[0][1]+b2*y.mat[1][1])%mod); return node;//线性代数矩阵乘法 } }; Node Pow(Node a, int n) { Node node(1,0,0,1);//单位矩阵 // TODO: 矩阵的快速幂 while(n){ if(n&1){ node=node*a; } a=a*a; n>>=1; } return node; } signed main() { int n; while(scanf("%lld", &n) != EOF) { // TODO: 初始化用于推导斐波那契数列的矩阵 Node x(0,1,1,1); Node ans = Pow(x, n-1); // TODO: 输出矩阵中对应的斐波那契第n项 printf("%lld\n",(ans.mat[0][0]+ans.mat[0][1])%mod); } return 0; }