斐波那契加求幂运算

斐波那契博大精深啊,还有求幂的迭代也有点意思

  1 //斐波那契有好多中方法
  2 #include <iostream>
  3 #include <deque>
  4 using namespace std;
  5
  6 //注意普通斐波那契,在太大数时就会发生越界,比如long long 只能存表示第92个数,这些都是小的斐波那契,当要大时,就得用大数方法了
  7 //用int ,只能到第46个,47就不行了,unsighed int 只能到92
  8 int fibnaq(int n)             //采用vector或者deque的方法,用2个元素的话需要用到reverse,用三个元素的话可以不用,或者用2个元素用队列也可以
  9 {
 10     if(n<=0)
 11         return -1;
 12     deque<int> d(2);
 13     d[0]=1;
 14     d[1]=1;
 15     if(n==1||n==2)
 16         return 1;
 17     for(int i=3;i<=n;i++)
 18     {
 19         int tmp=d.front();
 20         d.pop_front();
 21         d.push_front(tmp+d.back());
 22         reverse(d.begin(),d.end());
 23     }
 24     return d.back();
 25 }
 26 int fibnaq2(int n)                  //数组实现,时间O(n),空间O(n)
 27 {
 28     int *A=new int[n];
 29     A[0]=1;
 30     A[1]=1;
 31     if(n==1||n==2)
 32         return 1;
 33     for(int i=2;i<n;i++)
 34     {
 35         A[i]=A[i-1]+A[i-2];
 36     }
 37     delete[] A;
 38     return A[n-1];
 39 }
 40
 41 int fibnaq3(int n)  //迭代实现,时间O(n),空间O(1),其实就是vector的用3个int来做,辗转相加法
 42 {
 43     if(n<=0)
 44         return -1;
 45     int a=1,b=1,c;
 46     if(n==1||n==2)
 47         return 1;
 48     for(int i=3;i<=n;i++)
 49     {
 50         c=a+b;
 51         a=b;
 52         b=c;
 53     }
 54     return c;
 55 }
 56 long long fibnaq4(int n) //重头戏,公式法 f(n)=((1+根号5.0)的n次方-(1-根号5.0)的n次方)/((2.0的n次方)*根号5)
 57 {
 58     double gh5=sqrt(5.0);
 59     return (pow(1+gh5,n)-pow(1-gh5,n))/(pow(2.0,n)*gh5);
 60 }
 61
 62 /*
 63 斐波那契数列是二阶递推数列,所以存在一个2*2的矩阵A,使得:
 64 (Fn, Fn-1) = (Fn-1, Fn-2)*A
 65 求得A=(1   1)
 66       (1   0)
 67 (fn,fn-1) = (fn-1+fn-2,fn-2)
 68 (fn-1,fn-2) = (fn-1,fn-2)*A
 69 .....
 70 (fn,fn-1) = (f1,f0)*A^(n-1).
 71 f1=1,f0=0,f2=1.
 72 只求fn,可以直接(fn,fn-1)
 73 之所以能logn就是因为求幂运算可以采用二分法。
 74 那么求数列的第n项就是等于求矩阵A的第n-1次幂,计算的速度非常快,时间复杂度为O(logn)。
 75 首先我们用long long 型表示数列中的元素,它只能表示20位的整数,能表示的范围太小,最多第92个元素。
 76 */
 77
 78 void multiply(long long A[2][2],long long B[2][2],long long C[2][2])
 79 {
 80     //for(int i=0;i<2;i++)                      //这样是不行的,因为有覆盖问题,还真的必须拆开写
 81     //    for(int j=0;j<2;j++)
 82     //        for(int k=0;k<2;k++)
 83     //          C[i][j]+=A[i][k]*B[k][j];
 84     int tmp[4];
 85     tmp[0]=A[0][0]*B[0][0]+A[0][1]*B[1][0];
 86     tmp[1]=A[0][0]*B[0][1]+A[0][1]*B[1][1];
 87     tmp[2]=A[1][0]*B[0][0]+A[1][1]*B[1][0];
 88     tmp[3]=A[1][0]*B[0][1]+A[1][1]*B[1][1];
 89     C[0][0]=tmp[0];
 90     C[0][1]=tmp[1];
 91     C[1][0]=tmp[2];
 92     C[1][1]=tmp[3];
 93 }
 94
 95 int fibnaq5(int n)   //采用矩阵方法的O(logn)
 96 {
 97     if(n<=0)
 98         return -1;
 99     if(n<=2)
100         return 1;
101     long long result[2][2]={{1,0},{0,1}};             //单位阵
102     long long a[2][2]={{1,1},{1,0}};
103     n=n-1;                    //注意n-1次方
104     while(n)
105     {
106         if(n&1)
107             multiply(result,a,result);
108         multiply(a,a,a);
109         n>>=1;
110     }
111     return result[0][0];             //因为(1,0)*result【2】【2】,为(fn,fn-1),fn=result【0】【0】。还是看编程之美才行啊
112
113
114
115 //a的n次方,迭代方法
116 int pow(int a,int n)          //n必须是正的,否则移位死循环
117 {
118  int ans=1;
119  while(n)
120  {
121   if(n&1)             //如果n是奇数如n=5,则首次乘以a,ans=a,则移位后一直是偶数,直到最后一次,n==1时,为奇数,又把最开始的a乘上了;如果开始n是偶数,则一直未a*=a,直到最后一次,乘以1.
122                         //变成除以2也可以,但是不如移位好
123    ans*=a;
124   a*=a;
125   n>>=1;
126  // n/=2;                  //用n/=2,负数不会死循环,因为-1/2=0
127  }
128  return ans;
129 }
130
131 //递归求a的n次方
132 int pow2(int a,int n)
133 {
134     if(n==1)
135         return 1;
136     if(n==1)
137         return a;
138     int tmp=pow2(a,n/2);
139     if(n&1)
140         return a*tmp*tmp;
141     else
142         return tmp*tmp;
143 }
144
145
146 int main()
147 {
148     int n;
149     cin>>n;
150     cout<<fibnaq4(n)<<endl;
151     //cout<<pow2(2,4)<<endl;
152     system("pause");
153 }

斐波那契加求幂运算

时间: 2024-10-19 04:18:47

斐波那契加求幂运算的相关文章

斐波那契优化 快速幂+矩阵乘法

题目:你能求得第n个斐波那契数吗?0<n<maxlongint 由于结果太大,输出的结果mod32768 思路:一般的求斐波那契数列的方法有递归,动归,或者用滚动优化,但是空间复杂或者时间复杂度都太高了,现在有一种用矩阵加快速幂的优化算法,可以让时间复杂度维持在logn. 具体的 初始化一个2×2的矩阵,初始值为{1,0,0,1} 则分别代表{a2,a1,a1,a0},把此矩阵平方后得到{2,1,1,0}分别代表{a3,a2,a2,a1}如此下去,便可以得到规律,其实这个算法主要就是优化在快速

hdu 4549 M斐波那契数列(快速幂 矩阵快速幂 费马小定理)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4549: 题目是中文的很容易理解吧.可一开始我把题目看错了,这毛病哈哈. 一开始我看错题时,就用了一个快速幂来解,不用说肯定wa,看题目的通过率也不高,我想会不会有啥坑啊.然而我就是那大坑,哈哈. 不说了,直接说题吧,先讨论k=1,2,3;时的解.这应该会解吧,不多说了: 从第四项开始f(4)=a^1+b^2;f(5)=a^2+b^3;f(6)=a^3+b^5......; 看出来了吧,a上的指数成斐波

【C++】【斐波那契】求第几个斐波那契数字。

首先在头文件 whichfibonaccinumber.h 中写了一个使用加法的解法.没有验证输入数字是否小于0. #ifndef WHICHFIBONACCINUMBER_H_ #define WHICHFIBONACCINUMBER_H_ typedef unsigned long long uint64; // 简写unsigned long long,因为是64位,写作 uint64(意为:无符号int 64位) // max == 18446744073709551615,尽量保证不溢

斐波拉契数列求第N个;

递归写法: function fblq(a){ if(a == 1 || a == 2){ return 1; }else{ return fblq(a -1) + fblq(a -2); } } alert(fblq(6)); 非递归: function fibonacci(n){ var a,b,res; a = b = 1; for(var i=3;i<=n;i++){ res = a + b; a = b; b = res; } return res; } alert(fibonacci

斐波那契数列求余(蓝桥)

问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n. 输出格式 输出一行,包含一个整数,表示Fn除以10007的余数. 说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单. 样例输入 10 样例输出 55 样例输

斐波那契 矩阵快速幂

1 #include <iostream> 2 #include <cstdlib> 3 #include <cstring> 4 #include <queue> 5 #include <cstdio> 6 #include <algorithm> 7 #include <map> 8 #include <time.h> 9 #include <ext/pb_ds/assoc_container.hpp

斐波那契 递归 求某一个数

int fibonacci(int n) { if(n<=0) { return = 0; } if(n==1||n==2) { return =1; } return fibonacci(n-1)+fibonacci(n-2); ) 原文地址:https://www.cnblogs.com/daran/p/10694972.html

(java)有序表查找——折半查找,插值查找,斐波那契查找

有序表查找 /* 主函数 */ public class OrderTableSearch { public static void main(String[] args) { int [] a= {0,1,16,24,35,47,59,62,73,88,99}; System.out.println(FibonacciSearch(a, 10, 88)); System.out.println(InsertKeySearch(a, 10, 88)); System.out.println(Bi

斐波那契数与二分法的递归与非递归算法及其复杂度分析

1. 什么是斐波那契数? 这里我借用百度百科上的解释:斐波那契数,亦称之为斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列.费波那西数列.费波拿契数.费氏数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.--在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*),用文字来说,就是斐波那契数列列由 0 和 1 开始,之后的斐波那契数列系数就由之前的两数相加.特别指出:0不是第一