3054 - 斐波那契数列的简单升级

通过次数

0

提交次数

0

时间限制 : 1 秒 内存限制 : 128 MB

斐波那契数列大家肯定耳熟能详了吧,Fn=F(n-1)+F(n-2),n>=3,这里我们定义F(1)=F(2)=1,如果只要求Fn,是不是显得太水了,目测是的,所以我们现在来求一SUM=[F1]^4+[F(2)]^4+....[F(n)]^4的值,当然1<=n<=10^9,所以结果很大,要对10^9+7取余。雯神说“为什么不是求sigma(F[i]^我体重)呢?oh,it's too big”

Ps:[F(i)]^4代表F(i)4次方。

题目输入

输入一个数n,n=0时程序结束

题目输出

输出SUM%(10^9+7)的值

输入/输出样例

输入格式

1
2
3
0

输出格式

1
2
18

C++解答

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;

int n;
const int mod=1000000007;
struct Mat{
    long long m[6][6];
};

Mat mut(const Mat& a, const Mat& b)
{
    Mat c;
    for(int i=0;i<6;i++)
    {
        for(int j=0;j<6;j++)
        {
            c.m[i][j]=0;
            for(int k=0;k<6;k++)
            {
                c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod;
                c.m[i][j]%=mod;
            }
        }
    }
    return c;
}

Mat power(Mat a,long long p)
{
    Mat ans;
    memset(ans.m,0,sizeof(ans.m));
    for(int i=0;i<6;i++)
    {
        ans.m[i][i]=1;
    }
    while(p)
    {
        if(p%2==0)
        {
            a=mut(a,a);
            p/=2;
        }
        else
        {
            ans=mut(ans,a);
            p--;
        }
    }
    return ans;
}

int main()
{
   // freopen( "E.txt", "r", stdin );
   // freopen( "_E.txt", "w", stdout );
    while(cin>>n)
    {
        if(n==0)
            return 0;

        if(n==1)
        {
            cout<<1<<endl;
        }
        else if(n==2)
        {
            cout<<2<<endl;
        }
        else
        {
            Mat ans;
            memset(ans.m,0,sizeof(ans.m));
            ans.m[0][0]=ans.m[0][4]=ans.m[1][0]=ans.m[1][3]=ans.m[2][0]=ans.m[2][2]=1;
            ans.m[3][0]=ans.m[3][1]=ans.m[4][0]=ans.m[5][0]=ans.m[5][4]=ans.m[5][5]=1;
            ans.m[0][1]=ans.m[0][3]=ans.m[5][1]=ans.m[5][3]=4;
            ans.m[1][1]=ans.m[1][2]=3;
            ans.m[2][1]=2;
            ans.m[0][2]=ans.m[5][2]=6;
            ans=power(ans,n-2);
            long long res = 0;
            for(int i=0;i<5;i++) res+=ans.m[5][i];
            res+=ans.m[5][5]*2;
            cout<<res%mod<<endl;
        }
    }
    return 0;
}