列表

详情


OR9. 斐波拉契加强版

描述

对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - 1) + F(n - 2),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围内的非负整数,请设计一个高效算法,计算第n项F(n-1)。第一个斐波拉契数为F(0) = 1。

给定一个非负整数,请返回斐波拉契数列的第n项,为了防止溢出,请将结果Mod 1000000007。

测试样例:
3
返回:2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 2ms, 内存消耗: 376KB, 提交时间: 2020-10-31

class Fibonacci {
     int tmp[2][2], now[2][2];
      inline int addmul(int a, int m0, int m1)
      {
            return (a + (long long) m0 * m1) % 1000000007;
      }
      void mul(int C[][2], int A[][2], int dime)
      {
            int i, j, k;
            memcpy(tmp, C, sizeof (tmp));
            for (i = 0; i < dime; i++)
                  for (j = 0; j < dime; j++)
                  {
                        int t = 0;
                        for (k = 0; k < dime; k++)
                        {
                              t = addmul(t, A[i][k], tmp[k][j]);
                        }
                        C[i][j] = t;
                  }
      }
      void getpow(int res[][2], int mat[][2], int n, int dime)
      {
            memcpy(now, mat, sizeof (now));
            memset(res, 0, sizeof (now));
            for (int i = 0; i < dime; i++)
                  res[i][i] = 1;
            while (n != 0)
            {
                  if (n & 1)
                  {
                        mul(res, now, dime);
                  }
                  n >>= 1;
                  mul(now, tmp, dime);
            }
      }

public:
    int getNthNumber(int n) {
        // write code here
        if(n<2)return 1;
        int res[2][2],A[2][2]={{1,1},{1,0}};
        getpow(res,A,n,2);
        return res[0][0];
    }
};

C++ 解法, 执行用时: 2ms, 内存消耗: 396KB, 提交时间: 2020-10-31

class Fibonacci {
     int tmp[2][2], now[2][2];
      inline int addmul(int a, int m0, int m1)
      {
            return (a + (long long) m0 * m1) % 1000000007;
      }
      void mul(int C[][2], int A[][2], int dime)
      {
            int i, j, k;
            memcpy(tmp, C, sizeof (tmp));
            for (i = 0; i < dime; i++)
                  for (j = 0; j < dime; j++)
                  {
                        int t = 0;
                        for (k = 0; k < dime; k++)
                        {
                              t = addmul(t, A[i][k], tmp[k][j]);
                        }
                        C[i][j] = t;
                  }
      }
      void getpow(int res[][2], int mat[][2], int n, int dime)
      {
            memcpy(now, mat, sizeof (now));
            memset(res, 0, sizeof (now));
            for (int i = 0; i < dime; i++)
                  res[i][i] = 1;
            while (n != 0)
            {
                  if (n & 1)
                  {
                        mul(res, now, dime);
                  }
                  n >>= 1;
                  mul(now, tmp, dime);
            }
      }

public:
    int getNthNumber(int n) {
        // write code here
        if(n<2)return 1;
        int res[2][2],A[2][2]={{1,1},{1,0}};
        getpow(res,A,n,2);
        return res[0][0];
    }
};

C++ 解法, 执行用时: 2ms, 内存消耗: 424KB, 提交时间: 2021-09-29

class Fibonacci {
public:
    void MultMetri(long long base1[2][2],long long base2[2][2])
    {
        long long tmp[2][2]={0};
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<2;j++)
                tmp[i][j]=(base1[i][0]*base2[0][j]+base1[i][1]*base2[1][j])%1000000007;
        }
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<2;j++)
                 base1[i][j]=tmp[i][j];
        }
    }
    int getNthNumber(int n) {
       long long base[2][2]={{1,1},{1,0}};
       long long ret[2][2]={{1,0},{1,0}};
        while(n)
        {
            if(n%2)
                MultMetri(ret,base);
            MultMetri(base,base);
            n=n/2;
        }
        return (int)(ret[0][0]);
    }
};

C++ 解法, 执行用时: 2ms, 内存消耗: 432KB, 提交时间: 2022-03-05

#include <algorithm>
#include <string.h>

    const long long Mod =  1e9+7;
class Fibonacci {


public:
struct Matrix {
    long long a[3][3];
    Matrix() { memset(a, 0, sizeof a); }
    Matrix operator*(const Matrix &b) const {//重载矩阵乘法
        Matrix res;
        for (int i = 1; i <= 2; ++i)
            for (int j = 1; j <= 2; ++j)
                for (int k = 1; k <= 2; ++k)
                    res.a[i][j] = (res.a[i][j] + a[i][k] * b.a[k][j]%Mod) % Mod;
        return res;
    }
}ans,base;//初始矩阵ans,乘法矩阵base

void init() {
    base.a[1][1] = 1;
    base.a[1][2] = 1;
    base.a[2][1] = 1;
    base.a[2][2] = 0;
    //base.a[3][1] = 1;
    //base.a[3][3] = 1;
    ans.a[1][1] = 1;
    ans.a[1][2] = 1;
    //ans.a[1][3] = 0;
}

void qpow(int b) {//矩阵快速乘
    while (b) {
        if (b & 1) ans = ans * base;
        base = base * base;
        b >>= 1;
    }
}
    int getNthNumber(int n) {
        
        init();
        if(n <= 1)
        {
            return 1;
        }
        if(n == 2)
        {
            return 2;
        }
        else
        {
            qpow(n-1);
            return ans.a[1][1]%Mod;
        }
        // write code here
    }
};

C++ 解法, 执行用时: 2ms, 内存消耗: 480KB, 提交时间: 2020-11-01

class Fibonacci {
     int tmp[2][2], now[2][2];
      inline int addmul(int a, int m0, int m1)
      {
            return (a + (long long) m0 * m1) % 1000000007;
      }
      void mul(int C[][2], int A[][2], int dime)
      {
            int i, j, k;
            memcpy(tmp, C, sizeof (tmp));
            for (i = 0; i < dime; i++)
                  for (j = 0; j < dime; j++)
                  {
                        int t = 0;
                        for (k = 0; k < dime; k++)
                        {
                              t = addmul(t, A[i][k], tmp[k][j]);
                        }
                        C[i][j] = t;
                  }
      }
      void getpow(int res[][2], int mat[][2], int n, int dime)
      {
            memcpy(now, mat, sizeof (now));
            memset(res, 0, sizeof (now));
            for (int i = 0; i < dime; i++)
                  res[i][i] = 1;
            while (n != 0)
            {
                  if (n & 1)
                  {
                        mul(res, now, dime);
                  }
                  n >>= 1;
                  mul(now, tmp, dime);
            }
      }

public:
    int getNthNumber(int n) {
        // write code here
        if(n<2)return 1;
        int res[2][2],A[2][2]={{1,1},{1,0}};
        getpow(res,A,n,2);
        return res[0][0];
    }
};

上一题