3070 Fibonacci(O(log n)求解 )
2011-10-17 23:01
453 查看
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)求出。
快速幂乘代码:
完整版代码:
由此公式可知:
设矩阵为{x,y,y,z} 根据Fibonacci性质可知:z=x-y;
所以这个矩阵我们每次只需计算一半
x=x*x+y*y;
y=x*y+y*(x-y);
所以有如下简洁代码:
设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);
所以有如下简洁代码:
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define mod 10000 int 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)); } }
相关文章推荐
- POJ-3070-Fibonacci-求Fibonacci的矩阵方法,O(log(n))
- poj 3070-Fibonacci-矩阵幂乘
- poj--3070 fibonacci的矩阵幂做法
- poj 3070 Fibonacci(矩阵快速幂)
- iOS10下UIWebView加载页面时出现log求解
- 三种方法求解Fibonacci(斐波那契)数列
- POJ-3070 Fibonacci【矩阵二分幂】
- POJ 3070 Fibonacci(简单矩阵快速幂)
- poj-3070 Fibonacci(矩阵快速幂 + 斐波那契数列)
- poj 3070 Fibonacci (矩阵快速幂)
- POJ 3070 Fibonacci
- poj 3070 Fibonacci 矩阵快速幂
- POJ - 3070 - Fibonacci ( 矩阵快速幂 )
- poj3070 Fibonacci ——矩阵快速幂
- POJ 3070 Fibonacci
- poj 3070 Fibonacci(矩阵快速幂)
- poj 3070 Fibonacci(矩阵快速幂)
- poj 3070 Fibonacci(矩阵运算)
- [poj 3070] Fibonacci
- POJ 3070 Fibonacci