zoukankan      html  css  js  c++  java
  • [HNOI 2011] 数学作业

    [题目链接]

              https://www.lydsy.com/JudgeOnline/problem.php?id=2326

    [算法]

            .矩阵乘法即可

             时间复杂度 : O(logN)

    [代码]

              

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    
    ll n;
    int m;
    int mat[4][4];
    ll pw[20];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline int len(ll x)
    {
            int ret = 0;
            while (x > 0) ++ret , x /= 10;
            return ret;
    }
    inline void multipy(int a[4][4] , int b[4][4])
    {
            int ret[4][4];
            memset(ret , 0 , sizeof(ret));
            for (int i = 1; i <= 3; i++)
            {
                    for (int j = 1; j <= 3; j++)
                    {
                            for (int k = 1; k <= 3; k++)
                            {
                                    ret[i][j] = (ret[i][j] + 1ll * a[i][k] % m * b[k][j] % m) % m;
                            }
                    }
            }
            for (int i = 1; i <= 3; i++)
            {
                    for (int j = 1; j <= 3; j++)
                    {
                            a[i][j] = ret[i][j];
                    }
            }
    }
    inline void exp_mod(int base[4][4] , ll n)
    {
            int ret[4][4];
            for (int i = 1; i <= 3; i++)
            {
                    for (int j = 1; j <= 3; j++)
                    {
                            ret[i][j] = (i == j); 
                    }
            }
            while (n > 0)
            {
                    if (n & 1) multipy(ret , base);
                    multipy(base , base);
                    n >>= 1;
            }
            for (int i = 1; i <= 3; i++)
            {
                    for (int j = 1; j <= 3; j++)
                    {
                            base[i][j] = ret[i][j];
                    }
            }
    }
    
    int main()
    {
            
            read(n); read(m);
            int L = len(n);
            pw[0] = 1;
            for (int i = 1; i <= L; i++) pw[i] = pw[i - 1] * 10;
            int ans = 0;
            for (int i = 1; i < L; i++)
            {
                    mat[1][1] = (1ll * pw[i] % m); mat[1][2] = 1; mat[1][3] = 0;
                    mat[2][1] = 0; mat[2][2] = 1; mat[2][3] = 1;
                    mat[3][1] = 0; mat[3][2] = 0; mat[3][3] = 1;
                    exp_mod(mat , pw[i] - pw[i - 1]);        
                    ans = (1ll * mat[1][1] % m * ans % m + 1ll * mat[1][2] % m * (pw[i - 1] % m) + mat[1][3] % m) % m;
            }
            mat[1][1] = pw[L] % m; mat[1][2] = 1; mat[1][3] = 0;
            mat[2][1] = 0; mat[2][2] = 1; mat[2][3] = 1;
            mat[3][1] = 0; mat[3][2] = 0; mat[3][3] = 1;
            exp_mod(mat , n - pw[L - 1] + 1);
            ans = (1ll * mat[1][1] * ans % m + 1ll * mat[1][2] * (pw[L - 1] % m) + mat[1][3] % m) % m;
            printf("%d
    " , ans);
            
            return 0;
        
    }
  • 相关阅读:
    webuploader之大文件分段上传、断点续传
    人民币数字金额转大写金额
    发现个delphi调用vc写的Dll中包括pchar參数报错奇怪现象
    HTML5 CSS3 专题 : 拖放 (Drag and Drop)
    Cts框架解析(6)-任务的运行
    vector draw 试用期结束的 激活方法
    15_Android中任务栈
    Android之——AIDL深入
    FZU 2155 盟国
    十分简洁的手机浏览器 lydiabox
  • 原文地址:https://www.cnblogs.com/evenbao/p/10459655.html
Copyright © 2011-2022 走看看