斐波那契数列

来源:互联网 发布:数据库防护产品 编辑:程序博客网 时间:2024/06/05 19:36

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

#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#define LL long long#define GETMOD %1000000007using 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;}
原创粉丝点击