• hdu3117之矩阵快速幂


    Fibonacci Numbers

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1362    Accepted Submission(s): 564

    Problem Description
    The Fibonacci sequence is the sequence of numbers such that every element is equal to the sum of the two previous elements, except for the first two elements f0 and f1 which are respectively zero and one.

    What is the numerical value of the nth Fibonacci number?
     
    Input
    For each test case, a line will contain an integer i between 0 and 10 8 inclusively, for which you must compute the ith Fibonacci number fi. Fibonacci numbers get large pretty quickly, so whenever the answer has more than 8 digits, output only the first and last 4 digits of the answer, separating the two parts with an ellipsis (“...”). 

    There is no special way to denote the end of the of the input, simply stop when the standard input terminates (after the EOF).
     
    Sample Input
    0 1 2 3 4 5 35 36 37 38 39 40 64 65
     
    Sample Output
    0 1 1 2 3 5 9227465 14930352 24157817 39088169 63245986 1023...4155 1061...7723 1716...7565

    分析:求F[n]的后四位可以用矩阵快速幂求

    重点在于如何求F[n]的前四位:

    已知F[n]的通项公式:a_n= frac{1}{sqrt{5}}left [ {left ( {frac{1+sqrt{5}}{2}} 
ight )^n-{}left ( {frac{1-sqrt{5}}{2}} 
ight )^n} 
ight ]=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;
    }


  • 相关阅读:
    Python函数篇(2)-递归函数、匿名函数及高阶函数(已更新)
    Python函数篇(1)-函数中的形参与实参(已更新)
    Pyhton基础篇(6)-非基本数据类型 --集合(已更新)
    Pyhton基础篇(5)-基本数据类型-列表、元组、字典(已更新)
    Pyhton基础篇(4)-基本数据类型-字符串详解(已更新)
    Pyhton基础篇(3)-Pycharm安装及运算符(已更新)
    Pyhton基础篇(2)-变量、用户输入及条件语句(已更新)
    Pyhton基础篇(1)-第一个Pyhton程序(已更新)
    gallery的3D效果的实现
    android 图片二维码识别和保存(一)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3241175.html
Copyright © 2020-2023  润新知