• P1397 [NOI2013]矩阵游戏


    传送门

    首先显然可以矩乘快速幂然后 $T$ 飞

    看一眼题解发现因为这一题矩阵的特殊性所以可以对矩阵的次数欧拉降幂

    然而我并不懂证明,所以我选择暴力乱搞的做法

    十进制快速幂,然后注意一下常数,还有矩阵乘的顺序,别反了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=1e6+7,mo=1e9+7;
    char n[N],m[N];
    struct Matrix {
        int a[3][3];
        Matrix () { memset(a,0,sizeof(a)); }
        inline Matrix operator * (const Matrix &tmp) const {
            Matrix res;
            res.a[1][1]=(1ll*a[1][1]*tmp.a[1][1]+1ll*a[1][2]*tmp.a[2][1])%mo;
            res.a[1][2]=(1ll*a[1][1]*tmp.a[1][2]+1ll*a[1][2]*tmp.a[2][2])%mo;
            res.a[2][1]=(1ll*a[2][1]*tmp.a[1][1]+1ll*a[2][2]*tmp.a[2][1])%mo;
            res.a[2][2]=(1ll*a[2][1]*tmp.a[1][2]+1ll*a[2][2]*tmp.a[2][2])%mo;
            //循环展开优化常数
            return res;
        }
    }F,G,Ans;
    Matrix ksm(Matrix x,char *y)//十进制快速幂
    {
        Matrix res,t; res.a[1][1]=res.a[2][2]=1;
        for(int i=strlen(y+1);i;i--)
        {
            t=x;
            if(y[i]=='9') { t=t*t; t=t*t; t=t*t; t=t*x; res=res*t; }
            else if(y[i]=='8') { t=t*t; t=t*t; t=t*t; res=res*t; }
            else for(int j=1;j<=y[i]-'0';j++) res=res*x;
            t=x; x=x*x; x=x*x; x=x*x; x=x*t; x=x*t;
        }
        return res;
    }
    void Minus(char *s)//把数减一
    {
        for(int i=strlen(s+1);i;i--)
            if(s[i]=='0') s[i]='9';
            else { s[i]=s[i]-1; break; }
    }
    int main()
    {
        int a,b,c,d; scanf("%s",n+1); scanf("%s",m+1);
        a=read(),b=read(),c=read(),d=read();
        Ans.a[1][1]=Ans.a[1][2]=1;
        F.a[1][1]=a; F.a[2][1]=b; F.a[2][2]=1;
        G.a[1][1]=c; G.a[2][1]=d; G.a[2][2]=1;
        Minus(n); Minus(m);
        F=ksm(F,m); G=F*G; G=ksm(G,n);
        Ans=Ans*G*F;
        printf("%d
    ",Ans.a[1][1]);
        return 0;
    }
  • 相关阅读:
    JDBCUtils
    C3P0配置
    反射基本常识(二)
    反射基本常识(一)
    String to Integer (atoi)
    ZigZag Conversion
    Longest Palindromic Substring
    Palindrome Number
    Reverse Integer
    Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11521638.html
Copyright © 2020-2023  润新知