快速矩阵幂HDU3117

来源:互联网 发布:qq堂mac版下载 编辑:程序博客网 时间:2024/05/29 14:50
题意:求斐波那契数,如果位数不超过8位就直接输出。
如果超过8位,就输出前四位+“...”+后四位。


分析:
打表发现前40项不超过8位。所以前40个直接输出。


最后超过8位的斐波那契数。
对于后4位用快速矩阵幂求出。
对于前4位,利用公式求出。
由f[n] = 1/sqrt(5)*(((1+sqrt(5))/2)^n-((1-sqrt(5))/2)^n)可知,
当n比较大时,(1-sqrt(5))/2)^n会变得很小,以至于它不会出现在前4位。
所以我们只需要计算1/sqrt(5)*( (1+sqrt(5))/2)^n ).假设等于t*10^k
利用对数进行求。即是先进行对数,
变成log10( 1/sqrt(5) )+n*log( ( 1+sqrt(5) )/2 ) .取掉整数,
也就是求留下,因为log10(t)<1,然后将其复原,即是pow(10.0,t)。

然后不断乘上10,直到大于等于1000,就是前4位了。


/*//////////////////////////////HDU 3117 快速矩阵幂//////////////////////////////*/#include <cstdio>#include <cstring>#include <cmath>int n,mod=10000;const double fib=(1+sqrt(5.0))/2.0;struct Matrix{    int m[2][2];void clear(){memset(m,0,sizeof(m));}}E, Z;Matrix Mut(Matrix A, Matrix B){    Matrix ans;    for (int i = 0; i<2; i++)        for (int j = 0; j<2; j++)        {            ans.m[i][j] = 0;            for (int k = 0; k<2; k++)            {                ans.m[i][j] += ((A.m[i][k])*(B.m[k][j]));                ans.m[i][j]%=mod;            }        }    return ans;}Matrix Pow(Matrix A, int b){    Matrix t = A, ans = E;    while (b)    {        if (b % 2) ans = Mut(ans, t);        b /= 2;        t = Mut(t, t);    }    return ans;}int front4(int n){//log10(1/sqrt(5.0))=log10(1)-log(sqrt(5.0))//=0 - 0.5 * log (5.0)double k=-0.5*( log10(5.0) )+n*log10(fib);k=k-(int)k;k=pow(10.0,k);while(k<1000)k*=10;return (int)k;}int main(){    // freopen("in.txt", "r", stdin);Matrix A;int f[50];f[0]=0;f[1]=1;for(int i=2;i<40;i++)  //打表列出前40项{f[i]=f[i-1]+f[i-2];}while(scanf("%d",&n)!=EOF){if(n<40){printf("%d\n",f[n]);continue;}//初始化AA.clear();A.m[0][0]=1;A.m[0][1]=1;A.m[1][0]=1;A.m[1][1]=0;E=A;//后4位。Matrix ans=Pow(E,n-2);int f4=front4(n);//注意格式printf("%d...%04d\n",f4,ans.m[0][0]);}    return 0;}


0 0
原创粉丝点击