HDU 3117 Fibonacci Numbers(斐波那契数列通项+矩阵快速幂)

来源:互联网 发布:如何看待微商 知乎 编辑:程序博客网 时间:2024/05/19 18:41
大意:

8位及以下的fib直接输出,8位以上的输出XXXX(fib前四位)...XXXX(fib后四位)。

思路:

8位以下的打表输出就好了。

fib的前四位可以利用通项公式fn=1/√5/*[(1+√5)^n/2)-(1-√5)^n/2]来求,利用对数知识求解。

例如:

log(2335566)=log(2.335566)+2.

那么log(2.335566)是log(2335566)的小数部分。

然后将log(2.335566)变为10的指数,

那么前四位就是所得的数在<10000时x10所得数的整数部分。

fib的后四位有两种求法,一是循环找出后四位的规律得到循环解,二是通过变换矩阵((1,1),(1,0))+矩阵快速幂求解。

#include <iostream>#include <math.h>#include <stdio.h>#include <string.h>using namespace std;struct matrix{    int a[11][11];    void clear()    {        memset(a,0,sizeof(a));    }    void clear1()    {        for(int i=0; i<11; i++)            a[i][i]=1;    }    void zhuanzhi()    {        a[0][0]=1;        a[0][1]=1;        a[1][0]=1;        a[1][1]=0;    }} danw,zhuan;matrix mul(matrix a,matrix b,int n,int mod){    matrix ans;    ans.clear();    for(int i=0; i<n; i++)        for(int j=0; j<n; j++)        {            for(int k=0; k<n; k++)            {                ans.a[i][j]+=(a.a[i][k]%mod*b.a[k][j]%mod)%mod;                ans.a[i][j]%=mod;            }        }    //ans.n=n;    return ans;}matrix Qmod(int k,matrix a,int mod,int n){    matrix ans=danw;    while(k)    {        if(k&1)            ans=mul(ans,a,n,mod);        k>>=1;        a=mul(a,a,n,mod);    }    return ans;}int main(){    const double geng5=sqrt(5);    int a[40];    a[0]=0,a[1]=1;    zhuan.zhuanzhi();    danw.clear1();    for(int i=2;i<40;i++)    {        a[i]=a[i-1]+a[i-2];        //cout<<a[i]<<" "<<i<<endl;    }    int n;    while(cin>>n)    {        if(n<=39)         cout<<a[n]<<endl;        else        {            double b=log10(1/geng5)+(double)n*log10((1+geng5)/2);            b=b-floor(b);            b=pow(10,b);            while(b<1000)             b*=10;            matrix ans=Qmod(n,zhuan,10000,2);            printf("%d...%04d\n",(int)b,ans.a[1][0]);        }    }    return 0;}



0 0
原创粉丝点击