A - Jzzhu and Sequences -矩阵快速幂

  1. 
    给定f1和f2,求fn
    分析:
    特判f1,f2
    当n>=3时使用矩阵快速幂即可
    将公式转化一下 , 可以得到一个变换矩阵
    由F(i)=F(i-1)+F(i+1);
     将左式移到右边得
      F(i+i)=F(i)-F(i-1);
    下标同时减一得
      F(i)=F(i-1)-F(i-2);
    从而构造矩阵
    (F(i-1),F(i-2))*[1 -1 ]=(F(i),F(i-1))
                    [1  0 ]
    带入i=3,得
    (F(2)=y,F(1)=x)*[1 -1 ]^(i-2)=(F(3),F(2))
                    [1  0 ]
    
    #include<bits/stdc++.h>
    using namespace std;
    long long n,x,y,mod=1000000007;
    #define ll long long
    struct mat
    {
        ll a[5][5];
    } ans,e,base;
    mat matrlc(mat x,mat y,int len)
    {
        mat c;
        for(int i=0; i<len; i++)
            for(int j=0; j<len; j++)
            {
                c.a[i][j]=0;
                for(int k=0; k<len; k++)
                {
                    c.a[i][j]+=x.a[i][k]*y.a[k][j];
                }
            }
        return c;
    }
    void qpow(mat x,ll b)
    {
        for(int i=0; i<2; i++)
            ans.a[i][i]=1;
        while(b)
        {
            if(b%2)
            {
                ans=matrlc(ans,x,2);
            }
            x=matrlc(x,x,2);
            b/=2;
        }
    }
    int main()
    {
        base.a[0][0]=1;
        base.a[0][1]=1;
        base.a[1][0]=-1;
        base.a[1][1]=0;
        cin>>x>>y>>n;
        if(n==1)
            cout<<((x%mod)+mod)%mod;
        else if(n==2)
            cout<<((y%mod)+mod)%mod;
        else
        {
            qpow(base,n-2);
            cout<<(((ans.a[0][0]*y+ans.a[1][0]*x)%mod)+mod)%mod<<endl;
        }
        return 0;
    }

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/82710952
今日推荐