斐波那契数列三重循环求和

版权声明:编写不易,转载请注明出处,谢谢。 https://blog.csdn.net/qingshui23/article/details/82318221

已知斐波那契数列 F ( n )

F ( n ) = { 1 n=1,2 F ( n 1 ) + F ( n 2 ) n>2

(1) f ( n ) = i = 1 n j = 1 i k = 1 j F ( k )

其实一看到这个题目,很显然想到矩阵快速幂,那么我们就根据这个思路往下想,那么我们写出 f ( n + 1 )
(2) f ( n + 1 ) = f ( n ) + j = 1 n + 1 k = 1 j F ( k )

我们令 g ( n + 1 ) = j = 1 n + 1 k = 1 j F ( k ) ,那么写出 g ( n + 1 ) 的递推式:
(3) g ( n + 1 ) = g ( n ) + k = 1 n + 1 F ( k )

我们令 s ( n + 1 ) = k = 1 n + 1 F ( k ) ,那么写出 s ( n + 1 ) 的递推式:
(4) s ( n + 1 ) = s ( n ) + F ( n + 1 )

所以,将式 ( 4 ) 带入 ( 3 ) 得到:
g ( n + 1 ) = g ( n ) + s ( n ) + F ( n + 1 )

一步步回代到 ( 2 ) ,最终 f ( n + 1 ) 的递推式为:
f ( n + 1 ) = f ( n ) + g ( n ) + s ( n ) + F ( n + 1 )

那么就有:
(5) { f ( n ) , g ( n ) , s ( n ) , F ( n + 1 ) , F ( n ) } A = { f ( n + 1 ) , g ( n + 1 ) , s ( n + 1 ) , F ( n + 2 ) , F ( n + 1 ) }

其中 A 5 5 的矩阵,那么矩阵 A 如下:
1 0 0 0 0 1 1 0 0 0 1 1 1 0 0 1 1 1 1 1 0 0 0 1 0

将式 5 变为下述式子:
{ f ( 1 ) , g ( 1 ) , s ( 1 ) , F ( 2 ) , F ( 1 ) } A n 1 = { f ( n + 1 ) , g ( n + 1 ) , s ( n + 1 ) , F ( n + 2 ) , F ( n + 1 ) }

那么最终的
f ( n + 1 ) = t m p [ 0 ] [ 0 ] + t m p [ 1 ] [ 0 ] + t m p [ 2 ] [ 0 ] + t m p [ 3 ] [ 0 ] + t m p [ 4 ] [ 0 ]

其中 t m p 为 矩阵 A n 1 计算后的结果。
代码如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
typedef long long LL;
const LL MOD = 1e9+7;
struct Matrix
{
    LL mat[5][5];
};
Matrix Multi(Matrix A, Matrix B)
{
    Matrix C;
    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
        {
            C.mat[i][j] = 0;
            for(int k=0; k<5; k++)
            {
                C.mat[i][j] = (C.mat[i][j]+A.mat[i][k]*B.mat[k][j]%MOD)%MOD;
            }
        }
    }
    return C;
}
Matrix Pow(Matrix A, LL b)
{
    Matrix ans;
    memset(ans.mat, 0, sizeof ans.mat);
    for(int i=0; i<5; i++) ans.mat[i][i] = 1;
    while(b)
    {
        if(b&1) ans=Multi(ans, A);
        b>>=1;
        A = Multi(A, A);
    }
    return ans;
}
int main()
{
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    int T; cin>>T;
    while(T--)
    {
        LL n; cin>>n;
        Matrix tmp;
        memset(tmp.mat, 0, sizeof tmp.mat);
        tmp.mat[0][0] = tmp.mat[1][0] = tmp.mat[2][0] = tmp.mat[3][0] = 1;
        tmp.mat[1][1] = tmp.mat[2][1] = tmp.mat[3][1] =  1;
        tmp.mat[2][2] = tmp.mat[3][2] = 1;
        tmp.mat[3][3] = tmp.mat[4][3] = 1;
        tmp.mat[3][4] = 1;
        tmp = Pow(tmp, n-1);
        LL ans=tmp.mat[0][0]+tmp.mat[1][0]+tmp.mat[2][0]+tmp.mat[3][0]+tmp.mat[4][0];
        ans = (ans%MOD+MOD)%MOD;
        cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qingshui23/article/details/82318221