codeforces 450B Jzzhu and Sequences

这题还有点意思,好像类似于斐波那契的递推式都可以用矩阵快速幂和找循环节的两种方法来做。

我的朴素算法(超时):

//B
#include<stdio.h>
#include<string.h>
typedef long long LL;
#define MOD 1000000007

LL f[4];

int main()
{
    LL i;
    LL n;

    while(scanf("%lld%lld%lld",&f[1],&f[2],&n)!=EOF)
    {
        for(i=3;i<=n;i++)
        {
            f[3]=(MOD+(f[2]-f[1]))%MOD;
            f[1]=f[2];
            f[2]=f[3];
        }
        if(n<=2)
            printf("%lld\n",(f[n]+MOD)%MOD);
        else
            printf("%lld\n",(f[3]+MOD)%MOD);
    }
    return 0;
}

还有一种循环节的方法:

https://blog.csdn.net/qingshui23/article/details/46831343

//B
#include<stdio.h>
#include<string.h>
typedef long long LL;
#define MOD 1000000007

int main()
{
    int i;
    LL n;
    LL x,y;
    LL ans;
    int t;

    while(scanf("%lld%lld%lld",&x,&y,&n)!=EOF)
    {
        if(n<=2)
        {
            if(n==1)
                ans=x;
            else
                ans=y;
        }
        else
        {
            t=n%6;
            if(t==3)
                ans=y-x;
            else if(t==4)
                ans=-x;
            else if(t==5)
                ans=-y;
            else if(t==0)
                ans=x-y;
            else if(t==1)
                ans=x;
            else if(t==2)
                ans=y;
        }
        while(ans<0)
            ans+=MOD;
        printf("%lld\n",ans%MOD);
    }
    return 0;
}

最后这种类型的题目正解是矩阵快速幂:

https://blog.csdn.net/zp___waj/article/details/52628370

//B
#include<stdio.h>
#include<string.h>
#define MOD 1000000007
typedef long long LL;

struct Matrix
{
    LL M[2][2];
};

Matrix Init(Matrix ans)
{
    memset(ans.M,0,sizeof(ans.M));
    for(int i=0;i<2;i++)
        ans.M[i][i]=1;
    return ans;
}

Matrix Multi(Matrix a,Matrix b)
{
    int i,j,k;
    Matrix res;

    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            res.M[i][j]=0;
            for(k=0;k<2;k++)
                res.M[i][j]=(res.M[i][j]+(a.M[i][k]*b.M[k][j])%MOD+MOD)%MOD;
        }
    }
    return res;
}

Matrix qpow(Matrix m,LL n)
{
    Matrix ans;

    ans=Init(ans);
    while(n)
    {
        if(n&1)
            ans=Multi(ans,m);
        n/=2;
        m=Multi(m,m);
    }
    return ans;
}

int main()
{
    LL x,y;
    LL n;
    LL Ans;

    while(scanf("%lld%lld%lld",&x,&y,&n)!=EOF)
    {
        if(n<=2)
        {
            if(n==1)
                Ans=x;
            else
                Ans=y;
        }
        else
        {
            Matrix m;
            memset(m.M,0,sizeof(m.M));
            m.M[0][0]=1;
            m.M[0][1]=-1;
            m.M[1][0]=1;
            m.M[1][1]=0;
            m=qpow(m,n-2);
            Ans=(m.M[0][0]*y%MOD+m.M[0][1]*x%MOD+MOD)%MOD;
        }
        while(Ans<0)
                Ans+=MOD;
        Ans%=MOD;
        printf("%lld\n",Ans);
    }
    return 0;
}

其实矩阵快速幂的核心代码本质上是和普通的快速幂是相同的,只是矩阵乘法的运算需要另外定义。

就单纯的矩阵快速幂而言,矩阵的初始化变成一个单位矩阵,这点很重要。

这里有一个细节问题需要重视:

如果写成:

好。。像。。就会出问题。。。。。

猜你喜欢

转载自blog.csdn.net/fx714848657/article/details/82084294