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
重点在于如何求F[n]的前四位:
已知F[n]的通项公式:=F[n]=d.xxx * 10^m;//d<10
则Log10(F[n])=m+log10(d.xxx)=log10(an),容易知道F[n]的前四位和m无关,只和d.xxx有关,所以现在就是如何求d.xxx了,an是已知的且n>=40时-(1-sqrt(5))^n/2^n太小了,不影响前四位,所以可以舍去,则只要求log10(an)中的log10(1/sqrt(5))+n*log((1+sqrt(5))/2)得到m.xxx只要m.xxx的小数部分0.xxx即可,0.xxx=log10(d.xxx),然后d.xxx=pow(10.0,0.xxx)
注:由计算可知n<40时F[n]<100000000,可以直接输出
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<math.h> #include<iomanip> #define INF 99999999 using namespace std; const int MAX=2; const int mod=10000; int array[MAX][MAX],sum[MAX][MAX]; int F[40]; void MatrixMult(int a[2][2],int b[2][2]){ int c[2][2]={0}; for(int i=0;i<2;++i){ for(int j=0;j<2;++j){ for(int k=0;k<2;++k){ c[i][j]+=a[i][k]*b[k][j]; } } } for(int i=0;i<2;++i){ for(int j=0;j<2;++j)a[i][j]=c[i][j]%mod; } } int Matrix(int k){ array[0][0]=array[0][1]=array[1][0]=1; array[1][1]=0; sum[0][0]=sum[1][1]=1; sum[0][1]=sum[1][0]=0; while(k){ if(k&1)MatrixMult(sum,array); MatrixMult(array,array); k>>=1; } return sum[0][0]; } int pre(int n){ double a=sqrt(5.0); double b=(1+a)/2; a=1/a; double s=log10(a)+n*log10(b); s=s-(int)s; double d=pow(10.0,s); return int(d*1000); } void Init(){//经计算发现n>=40时F[n]>=100000000 F[0]=0,F[1]=1; for(int i=2;i<40;++i)F[i]=F[i-1]+F[i-2]; } int main(){ Init(); int n; while(cin>>n){ if(n<40)cout<<F[n]<<endl; else{ cout<<pre(n);//输出前4位,前4位用F[n]的通项公式求 cout<<"..."; cout<<setfill('0')<<setw(4)<<Matrix(n-1)<<endl;//输出后4位,后四位用矩阵快速幂求 } } return 0; }