斐波那契数列

题意(原题):
求斐波那契数列第n项模10^9+7的值。n<=2^31-1
思路:
由于n很大,所以不能暴力。
考虑矩阵乘法。
[ 0 1 ] x [ 2 ] = [ 3 ]
[ 1 1 ] …[ 3 ] … [ 5 ]
那么把求出第一个矩阵的n-1次方后乘以[ 0 ]即可得出结果。
…………………………………………………………[ 1 ]
矩阵乘法的时候别忘记了模。
我不知道markdown怎么画矩阵,抱歉。
代码:

#include
#include
#include
#include
#define LL long long
#define GETMOD %1000000007
using namespace std;
struct node
{
    int xcnt,ycnt;LL a[110][110];
    node()
    {
        xcnt=ycnt=0;memset(a,0,sizeof(a));
    }
    void setxy(int x,int y)
    {
        xcnt=x;ycnt=y;
    }
};
node dw(int x)
{
    node ans;ans.setxy(x,x);
    for(int i=1;i<=x;i++)ans.a[i][i]=1;
    return ans;
}
node cf(node x,node y)
{
    node ans;ans.setxy(x.xcnt,y.ycnt);
    for(int i=1;i<=ans.xcnt;i++)
        for(int j=1;j<=ans.ycnt;j++)
            for(int k=1;k<=x.ycnt;k++)
                ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j]GETMOD)GETMOD;
    return ans;
}
node power(node x,int k)
{
    node ans=dw(x.xcnt);
    while(k)
    {
        if(k&1)ans=cf(ans,x);
        x=cf(x,x);
        k/=2;
    }
    return ans;
}
int main()
{
    int n;
    scanf("%d",&n);
    node opt;opt.setxy(2,2);opt.a[1][2]=1;opt.a[2][1]=1;opt.a[2][2]=1;
    opt=power(opt,n-1); 
    node ans;ans.setxy(2,1);ans.a[2][1]=1;
    ans=cf(opt,ans);
    printf("%lld\n",ans.a[2][1]);
    return 0;
}

你可能感兴趣的:(矩阵乘法,caioj,矩阵乘法,caioj)