Fibonacci数列矩阵表示 与 快速幂方法
来源:互联网 发布:制作新闻联播视频软件 编辑:程序博客网 时间:2024/05/22 03:13
问题背景:
http://soj.sysu.edu.cn/1863
给定N,M,求Fn % m的结果。
F[0]=0;
F[1]=1;
F[n]=F[n-1]+F[n-2], for n>1
如果用公式递推,由于n很大,超过Int的范围并且递推时间复杂度是O(n).
解题思路:
- Fibonacci数列的矩阵表示:
,矩阵的初始值是
- 因此需要求矩阵的幂,问题分解为两部分,矩阵乘法 + 快速幂;采用【快速幂】的方法,原理如下:
当b 为偶数时,a^b =a^(b/2) * a^(b/2),
当b 为奇数时,a^b =a*a^(b-1)
所以问题就转化为求a^(b/2)
<pre name="code" class="cpp">matrix fastMod(int n){if(n == 1)return base;/*matrix temp = base; matrix ans; ans[0][0] = ans[1][1] = 1; ans[0][1] = ans[1][0] =0; while(n){<span></span>if( n & 1) //如果n是奇数<span></span>ans = multiply(temp, ans);<span></span>n >>= 1; //相当于n除以2<span></span>temp = multiply(temp, temp); } return temp;<span></span>}非递归方法*/if(n & 1)return multiply(base, fastMod(n-1));else{matrix temp = fastMod(n>>1);return multiply(temp, temp);}}
数据结构:
struct matrix{int m[2][2];}base; //Fibonacci数列矩阵乘法表示的初始值
代码如下:
#include<iostream>#include<vector>using namespace std;struct matrix{int arr[2][2];}base; //Fibonacci数列矩阵乘法表示的初始值int m;//矩阵乘法函数matrix multiply(matrix a, matrix b){matrix temp;temp.arr[0][0] = (a.arr[0][0]*b.arr[0][0] + a.arr[0][1]*b.arr[1][0]) % m; <span style="white-space:pre"></span>temp.arr[0][1] = (a.arr[0][0]*b.arr[0][1] + a.arr[0][1]*b.arr[1][1]) % m; <span style="white-space:pre"></span>temp.arr[1][0] = (a.arr[1][0]*b.arr[0][0] + a.arr[1][1]*b.arr[1][0]) % m; <span style="white-space:pre"></span>temp.arr[1][1] = (a.arr[1][0]*b.arr[0][1] + a.arr[1][1]*b.arr[1][1]) % m; return temp;}matrix fastMod(int n){if(n == 1)return base;/*matrix temp = base; matrix ans; ans[0][0] = ans[1][1] = 1; ans[0][1] = ans[1][0] =0; while(n){<span style="white-space:pre"></span>if( n & 1) //如果n是奇数<span style="white-space:pre"></span>ans = multiply(temp, ans);<span style="white-space:pre"></span>n >>= 1; //相当于n除以2<span style="white-space:pre"></span>temp = multiply(temp, temp); } return temp;<span style="white-space:pre"></span>}非递归方法*/if(n & 1)return multiply(base, fastMod(n-1));else{matrix temp = fastMod(n>>1);return multiply(temp, temp);}}int main(){int t;unsigned int n;//matrix ans;cin >> t;while(t--){cin >> n >> m;if(n==0)cout << 0 << endl;else{//初始赋值base.arr[0][0] = base.arr[0][1] = base.arr[1][0] = 1;base.arr[1][1] = 0;cout << fastMod(n).arr[0][1] % m << endl;}}return 0;}
0 0
- Fibonacci数列矩阵表示 与 快速幂方法
- fibonacci数列矩阵快速幂
- 矩阵快速幂 求Fibonacci数列poj3070
- Codevs_P1250 Fibonacci数列(矩阵快速幂)
- Codevs_P1732 Fibonacci数列 2(矩阵快速幂)
- 矩阵快速幂求Fibonacci数列
- 【数论】矩阵快速幂求Fibonacci数列
- 矩阵快速幂入门 + 求Fibonacci数列
- Fibonacci数列(矩阵乘法快速幂)
- Fibonacci数列(矩阵乘法快速幂)
- 矩阵快速幂 CodeVS 1250 Fibonacci数列
- 【矩阵快速幂相乘求Fibonacci 数列】PKU-3070-Fibonacci
- POJ 3070 Fibonacci (矩阵快速幂 Fibonacci数列新求法)
- POJ-3070 Fibonacci(矩阵快速幂求Fibonacci数列)
- 快速Fibonacci数列,矩阵法
- Fibonacci 数列快速幂
- NYOJ 题目148 fibonacci数列(二)(矩阵快速幂)
- nyoj 148 fibonacci数列(二) 【矩阵快速幂】
- 写字符串内容到文件
- JAVA多线程并发变量控制方法之volatile修饰工作原理
- IOS打包发给其他人测试
- Android Zxing扫码加开灯效果实现
- c++和java中的public,protected,private
- Fibonacci数列矩阵表示 与 快速幂方法
- lianliankan android game v1
- Java POI读取excel的例子
- 读书记之《linux命令行与shell脚本编程大全》
- 十一月总结
- vs2010中添加解决方案目录下的文件夹如include到项目中
- 28个实用的源码/文档比较合并工具
- Lua过滤器协同
- Linux Namespaces机制