zoukankan      html  css  js  c++  java
  • POJ 3070 斐波那契数的非矩阵快速幂做法

    我们都知道以下公式:

    \[\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^n = \begin{bmatrix} f_{n+1} & f_n \\ f_n & f_{n-1} \end{bmatrix} \tag{1} \]

    再通过矩阵快速幂就可以快速计算斐波那契数,但若是没实现好很容易TLE。
    这里给出一种新的计算斐波那契数的方法,愿望能起到一种抛砖引玉的作用。

    首先将(1)式两边同时平方得:

    \[\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{2n} = \begin{bmatrix} f_{n+1} & f_n \\ f_n & f_{n-1} \end{bmatrix}^2 \]

    左边根据(1)式变换,右边矩阵相乘:

    \[\begin{bmatrix} f_{2n+1} & f_{2n} \\ f_{2n} & f_{2n-1} \end{bmatrix} = \begin{bmatrix} f_{n+1}^2+f_n^2 & f_n(f_{n+1}+f_{n-1}) \\ f_n(f_{n+1}+f_{n-1}) & f_{n-1}^2+f_n^2 \end{bmatrix} \tag{2} \]

    由(2)我们可得以下递推公式:

    \[\begin{cases} f_{2n} &= f_n(f_{n+1}+f_{n-1}) \\ \\ f_{2n+1} &= f_{n+1}^2+f_n^2 \end{cases} \]

    这样我们就可以避免使用矩阵,下面给出POJ 3070的实现:

    #include <map>
    #include <cstdio>
    using namespace std;
    const int mod = 1e4;
    
    map<int, int> dp;
    
    int f(int n)
    {
        if(dp.find(n) != dp.end())
            return dp[n];
    
        int h = n >> 1;
    
        if(n & 1) {
            int t1 = f(h+1);
            int t2 = f(h);
            t1 = t1 * t1 % mod;
            t2 = t2 * t2 % mod;
            dp[n] = (t1 + t2) % mod;
        } else {
            int t = (f(h-1) + f(h+1)) % mod;
            dp[n] = f(h) * t % mod;
        }
        return dp[n];
    }
    
    int main()
    {
        int n;
        dp[0] = 0;
        dp[2] = dp[1] = 1;
    
        while(scanf("%d", &n), ~n)
            printf("%d\n", f(n));
    }
    
  • 相关阅读:
    Android Native Hook技术(一)
    Android Native Hook技术(二)
    Dalvik源码阅读笔记(一)
    Dalvik源码阅读笔记(二)
    Android反调试笔记
    /dev/mem可没那么简单
    jenkins使用邮件功能
    docker 安装 oracle
    jstack
    docker network
  • 原文地址:https://www.cnblogs.com/sequix/p/8557284.html
Copyright © 2011-2022 走看看