求斐波那契数列的多种方法(有矩阵(附好模板))
来源:互联网 发布:二战德国知乎 编辑:程序博客网 时间:2024/05/16 12:21
f[1]=1; f[2]=2; f[n]=f[n-1]+f[n-2];
(1)递推
long long fib(int n){ if(n==1) return 1; if(n==2) return 2; return fib(n-1)+fib(n-2);}
(2) 循环
long long fib(int n){ long long a=1,b=2,c; if(n==1) return 1; if(n==2) return 2; for(int i=3;i<=n;i++) { c=a+b; a=b;b=c; } return c;}
(3)矩阵乘法(空间换时间)【可取模哦】
数列的递推公式由矩阵乘法表示为
进一步,可得
那我们如何计算
假设计算A的n次幂:
二阶矩阵的乘法满足结合律:A(BC)=(AB)C
法一:
令n=N/2;
1.若n为偶数,则A^N=A^n * A^n
2.若n为奇数,则A^N=A^n * A^n * A
举例:A^6=A^3 * A^3
A^7=A^3 * A^3 * A
//使用模板前需先分析f[2]=1还是2!!!!!!!!!!!!!!!!!!!!!(这里f[2]=1)void multiply(int c[2][2],int a[2][2],int b[2][2],int mod) { int tmp[4]; tmp[0]=a[0][0]*b[0][0]+a[0][1]*b[1][0]; tmp[1]=a[0][0]*b[0][1]+a[0][1]*b[1][1]; tmp[2]=a[1][0]*b[0][0]+a[1][1]*b[1][0]; tmp[3]=a[1][0]*b[0][1]+a[1][1]*b[1][1]; c[0][0]=tmp[0]%mod; c[0][1]=tmp[1]%mod; c[1][0]=tmp[2]%mod; c[1][1]=tmp[3]%mod; }//计算矩阵乘法,c=a*b int fibonacci(int n,int mod)//mod表示数字太大时需要模的数 { if(n==0)return 0; else if(n<=2)return 1;//这里表示第0项为0,第1,2项为1 int a[2][2]={{1,1},{1,0}}; int result[2][2]={{1,0},{0,1}};//初始化为单位矩阵 int s; n-=2; while(n>0) { if(n%2 == 1) multiply(result,result,a,mod); multiply(a,a,a,mod); n /= 2; }//二分法求矩阵幂 s=(result[0][0]+result[0][1])%mod;//结果 return s; }
法二:
“二进位为1需要乘,为0不需要乘”
以计算A^6为例:
A^6=A^4 * A^2
将6转换成二进制:110
第2位为1,需要乘,乘2^2(即A^4); 第1位还为1,需要乘,乘2^1(即A^2); 第0位为0,不需要乘。
即:若需要乘,则乘2^pos.
十进制7 = 二进制 111
则A^7=A^4∗A^2∗A^1
////使用模板前需先分析f[2]=1还是2!!!!!!!!!!!!!!!!!!!!!(这里f[2]=2)///求解fac(n)%100000,其中n为大于等于3的正整数#include<stdio.h>#include<math.h>long long fac_tmp[6][4]={ ///存放矩阵次幂 ///位置:00 01 10 11 {24578,78309,78309,46269}, ///32次幂%100000 {1597,987,987,610}, ///16次幂%100000 {34,21,21,13}, ///8次幂%100000 {5,3,3,2}, ///4次幂%100000 {2,1,1,1}, ///2次幂%100000 {1,1,1,0}, ///1次幂%100000 };void fac(int);int main(){ int n; scanf("%d",&n); fac(n); return 1;}void fac(int k) ///k>=3{ int i; long long t00=1,t01=1,t10=1,t11=0; ///表示矩阵的1次幂 long long a,b,c,d; k=k-3; ///公式中是n-2次幂,(t00,t01,t10,t11)表示1次幂。所以一共减3次 for(i=k;i>=32;i=i-32) ///对于大于等于32的k; { a=(t00*fac_tmp[0][0]+t01*fac_tmp[0][2])%100000; b=(t00*fac_tmp[0][1]+t01*fac_tmp[0][3])%100000; c=(t10*fac_tmp[0][0]+t11*fac_tmp[0][2])%100000; d=(t10*fac_tmp[0][1]+t11*fac_tmp[0][3])%100000; t00=a; t01=b; t10=c;t11=d; } i=4; while(i>=0) ///对于小于32的k(16,8,4,2,1); { if(k>=(long long)pow(2,i)) ///如果k大于某一个2的次幂 { a=(t00*fac_tmp[5-i][0]+t01*fac_tmp[5-i][2])%100000; ///(5-i):矩阵的2的i次幂在数组fac_tmp中的位置为fac_tmp[5-i] b=(t00*fac_tmp[5-i][1]+t01*fac_tmp[5-i][3])%100000; c=(t10*fac_tmp[5-i][0]+t11*fac_tmp[5-i][2])%100000; d=(t10*fac_tmp[5-i][1]+t11*fac_tmp[5-i][3])%100000; t00=a; t01=b; t10=c;t11=d; k=k-(int)pow(2,i); } i--; } a=(t00*2+t01*1)%100000; printf("%lld\n",a);}
(4) 直接上公式……
阅读全文
0 0
- 求斐波那契数列的多种方法(有矩阵(附好模板))
- 51nod 巨大的斐波那契数列(矩阵快速幂),递推式优化的好模板!!!!!!!
- *矩阵快速幂(斐波那契数列模板)
- 多种方法实现Fibonacci(斐波那契)数列的生成
- 斐波那契数列的第N项(矩阵快速幂模板)
- 矩阵连乘求斐波那契数列模板
- 1436 方程的解数 斐波那契数列+快速幂+矩阵快速幂(好题)
- 矩阵乘法求斐波那契数列(快速幂)
- 斐波那契数列的多种算法,迭代法+递归法+动态规划+矩阵幂
- 洛谷 P1939 【模板】矩阵加速(数列):优化递推式的方法——矩阵快速幂
- 矩阵乘法 求斐波那契数列
- 矩阵乘法 求斐波那契数列
- 矩阵乘法求斐波那契数列
- 利用矩阵求斐波那契数列
- 矩阵乘法求斐波那契数列
- 矩阵快速幂,求斐波那契数列
- 再论斐波那契数列(矩阵&快速幂)
- 斐波那契数列谈矩阵(1)
- tf.matmul()
- MySQL查询优化之explain的深入解析
- Android重构(二)
- 第一章 软件工程要点
- 502. IPO
- 求斐波那契数列的多种方法(有矩阵(附好模板))
- 代码在线自动生成工具,在线生成java代码,springmvc框架,mapper,实体类,控制器,页面代码
- 勾股数
- 深度理解链式前向星
- 【简单学】字体设置
- CF445E:DZY Loves Colors(线段树区间更新)^
- HDU-1159-Common Subsequence
- mysql 注释符号
- iOS日历、日期、时间的计算