• Ural Timus 1009 K-based Numbers (dp+矩阵快速幂+快速乘)


    题解思路:

    首先这此题是不准出现前导0和连续俩个位为0;

    也就是 如果是101进制,表示(100)10是(100)100 是有效的;

    首先dp[i]表示第i位有多少个有效数字;

    若i-1位为0 有效的数字 dp[i-2]*(k-1);

    若i-1位不为0 有效的数字 dp[i-1]*(k-1);

    所以 dp[i][j]=(dp[i-2]+dp[i-1])*(k-1);

    数据非常大 2 ≤ N, K, M ≤ 10^18. 用矩阵优化;

    构造矩阵

    0      1             dp[0];

    k-1 k-1            dp[1];

    还是数据的原因,10^18*10^18 会爆ll; 要用快速乘

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    
    #define int long long
    
    const int maxn=1e5+10;
    
    using namespace std;
    
    
    
    struct Matrix{
        int nmap[3][3];
    };
    
    Matrix I=
    {
        1,0,0,
        0,1,0,
        0,0,1,
    };
    
    Matrix T=
    {
        0,0,0,
        0,0,0,
        0,0,0,
    };
    
    int smul(int a,int b,int mod)
    {
        int s=0;
        while(b)
        {
            if(b&1) s=(s+a)%mod;
            b>>=1;
            a=(a+a)%mod;
        }
        return s%mod;
    }
    
    Matrix Matrix_mul(Matrix a,Matrix b,int mod)
    {
        Matrix A=T;
        for(int k=1;k<=2;k++)
        {
            for(int i=1;i<=2;i++)
            {
                if(a.nmap[i][k])
                for(int j=1;j<=2;j++)
                {
                    A.nmap[i][j]+=smul(a.nmap[i][k],b.nmap[k][j],mod);
                    A.nmap[i][j]%=mod;
                }
            }
        }
        return A;
    }
    
    Matrix Matrix_s(Matrix a,int b,int mod)
    {
        Matrix A=I;
        while(b)
        {
            if(b&1) A=Matrix_mul(A,a,mod);
            b>>=1;
            a=Matrix_mul(a,a,mod);
        }
        return A;
    }
    
    void put(Matrix a)
    {
        for(int i=1;i<=2;i++)
        {
            for(int j=1;j<=2;j++)
            {
                cout<<a.nmap[i][j]<<" ";
            }
            cout<<endl;
        }
        cout<<endl;
    }
    
    #undef int
    int main(){
    #define int long long
        int n,k,mod;
        while(~scanf("%lld%lld%lld",&n,&k,&mod))
        {
            Matrix A={
                0,0,0,
                0,0,1,
                0,k-1,k-1,
            };
            Matrix B={
                0,0,0,
                0,1,0,
                0,k-1,0,
            };
            //put(A);
            Matrix C=Matrix_s(A,n-1,mod);
            //put(C);
           // put(B);
            C=Matrix_mul(C,B,mod);
            //put(C);
            printf("%lld
    ",C.nmap[2][1]);
        }
        return 0;
    }
    
  • 相关阅读:
    华为机试题 成绩排名
    华为机试题 四则运算
    华为机试题 求最大连续bit数
    华为机试题 Redraiment
    华为机试题 素数伴侣
    华为机试题 字符串排序
    华为机试题 计算字符串的距离
    华为机试题 多线程
    UE4-快捷键-按键监听事件
    UE4-Blueprint Class-Actor-开关门-盒子触发体
  • 原文地址:https://www.cnblogs.com/minun/p/10473760.html
Copyright © 2020-2023  润新知