3070 Fibonacci(O(log n)求解 )
来源:互联网 发布:网络奇兵2剧情 编辑:程序博客网 时间:2024/06/03 10:34
Fibonacci序列可由此公式求出:
设a={1,1,1,0}
这样Fibonacci(n)可以由:a^n=a^(n/2)*a^(n/2) (n是偶数)
a^n=a^((n-1)/2)*a^((n-1)/2)*a (n是奇数)
这样和快速幂乘有些相似了,可以O(logn)求出。
快速幂乘代码:
// 快速计算 (n ^ p) % m 的值__int64 Montgomery(__int64 n, __int64 p, __int64 m) { __int64 r = n % m; __int64 k = 1; while (p > 1) { if ((p & 1)!=0) { k = (k * r) % m; } r = (r * r) % m; p /= 2; } return (r * k) % m;}
完整版代码:
#include<iostream>using namespace std;void fen(int r[][2], int k[][2]) { int ans[2][2]; ans[0][0] = (r[0][0] * k[0][0] % 10000 + r[0][1] * k[1][0] % 10000) % 10000; ans[0][1] = (r[0][0] * k[0][1] % 10000 + r[0][1] * k[1][1] % 10000) % 10000; ans[1][0] = (r[1][0] * k[0][0] % 10000 + r[1][1] * k[1][0] % 10000) % 10000; ans[1][1] = (r[1][0] * k[0][1] % 10000 + r[1][1] * k[1][1] % 10000) % 10000; r[0][0] = ans[0][0], r[0][1] = ans[0][1], r[1][0] = ans[1][0], r[1][1] = ans[1][1];}int fbnq(int num) { int k[2][2] = {1, 0, 0, 1}; int r[2][2] = {1, 1, 1, 0}; while (num > 1) { if ((num & 1) != 0) { fen(k, r); } fen(r, r); num /= 2; } fen(r, k); return r[0][1];}int main() { int num; while (cin >> num && num != -1) { if (num == 0) cout << 0 << endl; else cout << fbnq(num) << endl; } return 0;}
由此公式可知:
设矩阵为{x,y,y,z} 根据Fibonacci性质可知:z=x-y;
所以这个矩阵我们每次只需计算一半
x=x*x+y*y;
y=x*y+y*(x-y);
所以有如下简洁代码:
所以这个矩阵我们每次只需计算一半
x=x*x+y*y;
y=x*y+y*(x-y);
所以有如下简洁代码:
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define mod 10000int n;int fibonacci(int n) { int ra, rb, a, b, x, y; if (n < 2)return n; ra = rb = a = b = 1; n -= 2; while (n) { if (n & 1) { x = ra * a + rb*b; y = ra * b + rb * (a - b + mod); ra = x % mod; rb = y % mod; } n >>= 1; x = a * a + b*b; y = (2 * a + mod) * b - b*b; a = x % mod; b = y % mod; } return ra;}int main() { while (scanf("%d", &n) && n != -1) { printf("%dn", fibonacci(n)); }}
- 3070 Fibonacci(O(log n)求解 )
- POJ-3070-Fibonacci-求Fibonacci的矩阵方法,O(log(n))
- Fibonacci序列 —— O(log n)求Fibonacci数列(非矩阵法)
- fibonacci 数列实现 log(n) and O(n)
- 《编程之美》读书笔记08:2.9 Fibonacci序列 —— O(log n)求Fibonacci数列(非矩阵法)
- 快速幂( O(log n) )
- 约瑟夫环求解O(n)
- Fibonacci求解第n项(矩阵法)
- Fibonacci数列的log(n)解法
- 求解单个欧拉函数板子(O(sqrt(n)))
- 最长递增子序列的求解(O(n*n),O(nlogn))——动态规划
- C++ Fibonacci数列 O(2^n) 和 O(n)解法
- Fibonacci数列的第N项 log(N)算法(转)
- num的n次方 O(log(n))
- LIS O(n log n) 详解
- 利用矩阵求解fibonacci数列 时间复杂度为O(lgn)
- 数值的整数次方(剑指offer)O(log n)
- Fibonacci数列第n项的log(n)算法
- JavaScript正则表达式
- Android Service学习之AIDL, Parcelable和远程服务
- JDK1.6官方下载_JDK6官方下载地址:http://www.java.net/download
- 复习知识点
- Android 开发中使用 SQLite 数据库
- 3070 Fibonacci(O(log n)求解 )
- div图片marquee无缝连接
- 纠结的Python2.7编码与os.walk()函数的目录参数
- CLEMB命令根据参数和脚本用DB2存储过程当做数据源进行查询
- PHP的路径
- 状态dp 第一道
- objective-C: NSString应该用initWithFormat? 还是 stringWithFormat?
- Android的SQLite使用实例
- 了解framebuffer