标签:des style blog http color io os ar java
题目意思很简单:求第n个Fibonacci数,如果超过八位输出前四位和后四位中间输出...,否则直接输出Fibonacci数是多少。
后四位很好求,直接矩阵加速递推对10000取余的结果就是。
前四位搜了一下:http://blog.csdn.net/xieqinghuang/article/details/7789908
Fibonacci的通项公式,对,fibonacci数是有通项公式的——
f(n)=1/sqrt(5)(((1+sqrt(5))/2)^n+((1-sqrt(5))/2)^n)
假设F[n]可以表示成 t * 10^k(t是一个小数),那么对于F[n]取对数log10,答案就为log10 t + K,此时很明显log10 t<1,于是我们去除整数部分,就得到了log10 t ,
再用pow(10,log10 t)我们就还原回了t。将t×1000就得到了F[n]的前四位。 具体实现的时候Log10 F[n]约等于((1+sqrt(5))/2)^n/sqrt(5),这里我们把((1-sqrt(5))/2)^n这一项忽略了,
因为当N>=40时,这个数已经小的可以忽略。于是log10 F[n]就可以化简成log10 1/sqrt(5) + n*log10 (1+sqrt(5))/2
还有就是其实后四位存在一个循环节没15000个会重复一次。
0 1 2 3 4 5 35 36 37 38 39 40 64 65
0 1 1 2 3 5 9227465 14930352 24157817 39088169 63245986 1023...4155 1061...7723 1716...7565
#include <algorithm> #include <iostream> #include <stdlib.h> #include <string.h> #include <iomanip> #include <stdio.h> #include <string> #include <queue> #include <cmath> #include <stack> #include <map> #include <set> #define eps 1e-10 ///#define M 1000100 #define LL __int64 ///#define LL long long ///#define INF 0x7ffffff #define INF 0x3f3f3f3f #define PI 3.1415926535898 #define zero(x) ((fabs(x)<eps)?0:x) ///#define mod 9973 int mod; const int maxn = 2010; using namespace std; struct matrix { int f[110][110]; }; matrix mul(matrix a, matrix b, int n)///矩阵乘法 { matrix c; memset(c.f, 0, sizeof(c.f)); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { for(int k = 0; k < n; k++) c.f[i][j] += a.f[i][k]*b.f[k][j]; c.f[i][j] %= mod; } } return c; } matrix pow_mod(matrix a, int b, int n)///矩阵快速幂 { matrix s; memset(s.f, 0 , sizeof(s.f)); for(int i = 0; i < n; i++) s.f[i][i] = 1; while(b) { if(b&1) s = mul(s, a, n); a = mul(a, a, n); b >>= 1; } return s; } matrix Add(matrix a,matrix b, int n) ///矩阵加法 { matrix c; for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { c.f[i][j] = a.f[i][j]+b.f[i][j]; c.f[i][j] %= mod; } } return c; } LL num[maxn]; int main() { num[0] = 0LL; num[1] = 1LL; for(int i = 2; i <= 40; i++) num[i] = num[i-1]+num[i-2]; mod = 10000; int n; while(cin >>n) { if(n < 40) { cout<<num[n]<<endl; continue; } double ans; ans = -0.5*(log10(5.0))+n*log10((sqrt(5.0)+1.0)/2); ans -= (int)ans; ans = pow(10, ans); while(ans < 1000) ans *= 10; printf("%d",(int)ans); cout<<"..."; matrix c; memset(c.f, 0, sizeof(c.f)); c.f[0][0] = 1; c.f[0][1] = 1; c.f[1][0] = 1; matrix d; d = pow_mod(c, n-2, 2); int sum = 0; sum += d.f[0][0] + d.f[0][1]; sum %= mod; if(sum < 10) cout<<"000"; else if(sum < 100) cout<<"00"; else if(sum < 1000) cout<<"0"; cout<<sum<<endl; } return 0; }
HDU 3117 Fibonacci Numbers(Fibonacci矩阵加速递推+公式)
标签:des style blog http color io os ar java
原文地址:http://blog.csdn.net/xu12110501127/article/details/39666717