Fibonacci 数列快速幂

来源:互联网 发布:淘宝客最终佣金怎么算 编辑:程序博客网 时间:2024/05/17 02:17

Fibonacci 数列为:1,1,2,3,5,8...这样一个数列,其中F(1)=F(2)=1,F(n)=F(n-1)+F(n-2).

先介绍一下普通的迭代运算,时间复杂度是O(n),这里并没有讨论数目超大的情况,只是用long long来存储数列,没有考虑溢出的情况。

#include "iostream"using namespace std;int main(){int n;while (cin>>n){long long f_0 = 1, f_1 = 1; //定义初值long long f_2;              //设一个temp for (int i = 1; i < n; i++){f_2 = f_0 + f_1;   //进行赋值迭代f_0 = f_1;f_1 = f_2;}cout<<f_0<<endl;}return 0;}

接下来介绍一下矩阵的快速幂求法,用数学归纳法可以证明

当n = 2时,成立,

假设当n=k时,成立,

n=k+1时,成立,

所以,因此我们可以根据这个公式来求数列。

利用快速幂求

n为偶数时,

n为奇数时,

这样便可以把时间复杂度降低为O(log(n))。


#include "iostream"using namespace std;typedef struct{long long array[4];  //定义一个结构体用来存储一个数组}Matrix;Matrix multi(Matrix A, Matrix B) //矩阵乘法{Matrix C;C.array[0] = A.array[0]*B.array[0] + A.array[1]*B.array[2];C.array[1] = A.array[0]*B.array[1] + A.array[1]*B.array[3];C.array[2] = A.array[2]*B.array[0] + A.array[3]*B.array[2];C.array[3] = A.array[2]*B.array[1] + A.array[3]*B.array[3];C.array[0] %= 1000000007;   //对数值取模C.array[1] %= 1000000007;C.array[2] %= 1000000007;C.array[3] %= 1000000007;return C;}Matrix Mpow(Matrix a, int n)   //做快速幂的乘法{if(n == 1)                 //进行递归调用return a; else if( n % 2 == 0)   {Matrix tempa = Mpow(a, n/2);return multi(tempa, tempa);}else{Matrix tempb = Mpow(a, (n-1)/2);return multi(multi(tempb, tempb), a);}}int main(){int n;Matrix start;start.array[0] = 1;   //给矩阵赋初值start.array[1] = 1;start.array[2] = 1;start.array[3] = 0;while (cin>>n){if(n == 1)cout<<1<<endl;else{Matrix finish = Mpow(start, n-1);cout<<finish.array[0]<<endl;}}return 0;}

当时做的时候,还有一个细节是函数返回一个数组的时候该怎么做,后来学习别人的代码,发现可定义一个结构体来存储数组,在函数中直接更改结构体的数组中的数值就好了,之前的想法是直接申请一个数组,用指针来进行值的传递,最后没有成功。

0 0