zoukankan      html  css  js  c++  java
  • hdu 3117 Fibonacci Numbers 矩阵快速幂+公式

    斐波那契数列后四位可以用快速幂取模(模10000)算出。前四位要用公式推

    HDU 3117 Fibonacci Numbers(矩阵快速幂+公式)

    f(n)=(((1+√5)/2)^n+((1-√5)/2)^n)/√5

    假设F[n]可以表示成 t * 10^k(t是一个小数),那么对于F[n]取对数log10,答案就为log10 t + K,此时很明显log10 t<1,于是我们去除整数部分,就得到了log10

    再用pow(10,log10 t)我们就还原回了t。将t×1000就得到了F[n]的前四位。 具体实现的时候Log10 F[n]约等于((1+√5)/2)^n/√5,这里我们把((1-√5)/2)^n这一项忽略了,
    因为当N>=40时,这个数已经小的可以忽略。于是log10 F[n]就可以化简成log10 1/√5 + n*log10 (1+√5)/2

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    using namespace std;
    
    const int Mod = 10000;
    const int N = 4;
    int msize;
    
    struct Mat
    {
        int mat[N][N];
    };
    
    Mat operator *(Mat a, Mat b)
    {
        Mat c;
        memset(c.mat, 0, sizeof(c.mat));
        for(int k = 0; k < msize; ++k)
            for(int i = 0; i < msize; ++i)
                if(a.mat[i][k])
                    for(int j = 0; j < msize; ++j)
                        if(b.mat[k][j])
                            c.mat[i][j] = (c.mat[i][j] +a.mat[i][k] * b.mat[k][j])%Mod;
        return c;
    }
    
    Mat operator ^(Mat a, int k)
    {
        Mat c;
        memset(c.mat,0,sizeof(c.mat));
        for(int i = 0; i < msize; ++i)
            c.mat[i][i]=1;
        for(; k; k >>= 1)
        {
            if(k&1) c = c*a;
            a = a*a;
        }
        return c;
    }
    
    int a[50];
    const double sq5 = sqrt(5.0);
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        int n;
        msize = 2;
        Mat A;
        A.mat[0][0] = 1;
        A.mat[0][1] = 1;
        A.mat[1][0] = 1;
        A.mat[1][1] = 0;
        a[0] = 0;
        a[1] = 1;
        for(int i=2;i<40;i++)
            a[i] = a[i-1] + a[i-2];
        while(~scanf("%d", &n))
        {
            if(n<40) printf("%d
    ",a[n]);
            else
            {
                double t = n * log10((1.0 + sq5) / 2) - log10(sq5);
                t -= (int)t;
                t = pow(10.0, t);
                printf("%d...",(int)(t * 1000));
                Mat aa = A;
                aa = aa ^ (n-1);
                printf("%04d
    ",aa.mat[0][0]);
            }
        }
        return 0;
    }
  • 相关阅读:
    免费的视频、音频转文本
    Errors are values
    Codebase Refactoring (with help from Go)
    Golang中的坑二
    Cleaner, more elegant, and wrong(msdn blog)
    Cleaner, more elegant, and wrong(翻译)
    Cleaner, more elegant, and harder to recognize(翻译)
    vue控制父子组件渲染顺序
    computed 和 watch 组合使用,监听数据全局数据状态
    webstorm破解方法
  • 原文地址:https://www.cnblogs.com/pach/p/7231061.html
Copyright © 2011-2022 走看看