哈尔滨理工大学软件学院ACM程序设计全国邀请赛(网络同步赛)F Fibonacci Again

来源:互联网 发布:预约抢号软件 编辑:程序博客网 时间:2024/05/01 22:56


手推一下发现每6个为一节,然后就能构造出矩阵,然后就是矩阵快速幂了。下面给代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>typedef long long ll;using namespace std;const int MOD=1e9+7;int n=7;ll b[20][20]={    {13,8,0,0,0,0,-2},    {8,5,0,0,0,0,-2},    {5,3,0,0,0,0,-1},    {3,2,0,0,0,0,-1},    {2,1,0,0,0,0,-1},    {1,1,0,0,0,0,0},    {0,0,0,0,0,0,1}};struct Matrix{    ll a[20][20];    Matrix()//初始化矩阵    {        memset(a,0,sizeof(a));        for(int i=0;i<20;i++)a[i][i]=1;    }    void init()    {    memcpy(a,b,sizeof(a));    }    void show()    {        for(int i=0;i<n;i++)        {            for(int j=0;j<n;j++)            {                cout<<a[i][j]<<" ";            }            cout<<endl;        }    }};Matrix matrixmul(Matrix a,Matrix b,int grid)// grid*grid 矩阵相乘{    Matrix c;    for(int i=0;i<grid;i++)    {      for(int j=0;j<grid;j++)      {         c.a[i][j]=0;         for(int k=0;k<grid;k++)         {            c.a[i][j]+=a.a[i][k]*b.a[k][j];            c.a[i][j]%=MOD;         }      }   }   return c;}Matrix matrixquickpow(Matrix a,int time)//矩阵a的time次方{    Matrix b;    while(time>0)    {        if(time&1)b=matrixmul(b,a,n);        time=time>>1;        a=matrixmul(a,a,n);    }    return b;}int main(){    n=7;    ll time;    while(~scanf("%lld",&time))    {    if(time==0){ cout<<7<<endl;continue;}    else if(time==1){cout<<11<<endl; continue;}    Matrix x;    x.init();    int p=(time-2)%6;    p=5-p;    time=((time-2)/6)+1;    x=matrixquickpow(x,time-1);    ll ans=0;    int temp[8]={197,121,75,46,28,18,1};    for(int i=0;i<8;i++)    {        ans+=x.a[p][i]*temp[i];        ans=(ans%MOD+MOD)%MOD;    }    printf("%lld\n",ans%MOD);    }  }


0 0
原创粉丝点击