• 2020牛客寒假算法基础集训营1----J-u's的影响力 (费马小定理+矩阵快速幂)


    题目链接:https://ac.nowcoder.com/acm/contest/3002/J

    题意:给出一个递推式: f[i]=f[i-2] * f[i-1] * ab。并且 f[1] = x , f[2] = y , 其中x,y,a,b<=1e12,求第n项f[n]。(n<=1e12

    思路:

      首先列出前几项的表达式如下:

       我们可以发现根据递推式发现,x的系数:fx(i) = fx(i-2) +fx(i-1),y的系数:fy(i) = fy(i-2) +fy(i-1),a的系数:fa(i) = fa(i-2) +fa(i-1)+b。于是可以用矩阵快速幂来求系数。然后根据费马小定理知道矩阵快速幂过程中的模数MODD=1e9+6

    AC代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    const int MOD=1e9+7;
    const int MODD=1e9+6;
    typedef long long LL;
    LL n,x,y,a,b;
    int up;
    
    struct Mat{
        LL m[5][5];
        Mat(){memset(m,0,sizeof(m));}
    };
    
    LL qpow(LL a,LL b){
        LL ret=1;
        a%=MOD;
        while(b){
            if(b&1) ret=ret*a%MOD;
            a=a*a%MOD;
            b>>=1;
        }
        return ret;
    }
    
    Mat Matmul(Mat a,Mat b){
        Mat ret;
        for(int i=1;i<=up;++i)
            for(int j=1;j<=up;++j)
                for(int k=1;k<=up;++k){
                    ret.m[i][j]+=a.m[i][k]*b.m[k][j]%MODD;
                    ret.m[i][j]%=MODD;
                }
        return ret;
    }
    
    Mat Matqpow(Mat a,LL b){
        Mat ret;
        for(int i=1;i<=up;++i) ret.m[i][i]=1;
        while(b){
            if(b&1) ret=Matmul(ret,a);
            a=Matmul(a,a);
            b>>=1;
        }
        return ret;
    }
    
    int main(){
        scanf("%lld%lld%lld%lld%lld",&n,&x,&y,&a,&b);
        x%=MOD,y%=MOD,a%=MOD,b%=MOD-1;
        if(n==1){
            printf("%lld
    ",x);
            return 0;
        }
        else if(n==2){
            printf("%lld
    ",y);
            return 0;
        }
        else if(x==0||y==0||a==0){
            printf("0
    ");
            return 0;
        }
        else{
            up=2;
            Mat mx1,mx2;
            mx1.m[1][1]=mx1.m[1][2]=mx1.m[2][1]=1;
            mx2.m[2][1]=1;
            mx1=Matqpow(mx1,n-2);
            mx1=Matmul(mx1,mx2);
            LL res1=qpow(x,mx1.m[1][1]);
    
            Mat my1,my2;
            my1.m[1][1]=my1.m[1][2]=my1.m[2][1]=1;
            my2.m[1][1]=1;
            my1=Matqpow(my1,n-2);
            my1=Matmul(my1,my2);
            LL res2=qpow(y,my1.m[1][1]);
    
            up=3;
            Mat ma1,ma2;
            ma1.m[1][1]=ma1.m[1][2]=ma1.m[1][3]=ma1.m[2][1]=ma1.m[3][3]=1;
            ma2.m[3][1]=b;
            ma1=Matqpow(ma1,n-2);
            ma1=Matmul(ma1,ma2);
            LL res3=qpow(a,ma1.m[1][1]);
    
            LL ans=res1*res2%MOD*res3%MOD;
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    TyporaRecord
    c# 串口 应答式顺序下发命令 循环 间隔发送指令
    WPF 如何在单独的配置文件中使用Log4net
    UWP VisualStateManager
    USB通信
    UWP RelativePanel
    JSON 序列化与反序列化
    Unity 依赖注入的三种常用模板
    IOC Unity容器的基本使用
    使用EF完成基于SQLite的CodeFirst
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/12273184.html
Copyright © 2020-2023  润新知