zoukankan      html  css  js  c++  java
  • Codechef Eugene and big number(矩阵快速幂)

    题目链接 Eugene and big number

    题目转化为

    $f(n) = m * f(n - 1) + a$

    $f(n + 1) = m * f(n) + a$

    两式相减得

    $f(n + 1) = (m + 1) * f(n) - m * f(n - 1)$

    求$f(n)$

    其中$m$为$10^{k}$ ($k$为$a$的位数)

    那么利用矩阵快速幂加速就可以了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)    for (int i(a); i <= (b); ++i)
    
    typedef long long LL;
    
    struct Matrix{ LL arr[5][5];}  init, unit, Unit;
    
    int T;
    LL a, n, mod;
    
    inline LL Pow(LL a, LL b, LL Mod){
           LL ret(1); for (; b; b >>= 1, (a *= a) %= Mod) if (b & 1) (ret *= a) %= Mod; return ret;
    }
    
    Matrix Mul(Matrix a, Matrix b){
        Matrix c;
        rep(i, 1, 2) rep(j, 1, 2){
            c.arr[i][j] = 0;
            rep(k, 1, 2) (c.arr[i][j] += (a.arr[i][k] * b.arr[k][j] % mod)) %= mod;
        }
        return c;
    }
    
    Matrix MatrixPow(Matrix a, LL k){
        Matrix ret(Unit); for (; k; k >>= 1, a = Mul(a, a)) if (k & 1) ret = Mul(ret, a); return ret;
    }    
    
    
    inline LL calc(LL n){
        LL ret(0); for (; n; n /= 10) ++ret;
        return ret;
    }
    
    int main(){
    
        scanf("%d", &T);
        while (T--){
            Unit.arr[1][1] = Unit.arr[2][2] = 1;
            scanf("%lld%lld%lld", &a, &n, &mod);
            if (a == 0LL){
                puts("0");
                continue;
            }
            LL exp = calc(a), m = Pow(10, exp, mod);
            LL f1 = a % mod, f2 = ((f1 * m) % mod + a) % mod;
            LL f3 = ((f2 * m) % mod + a) % mod;
            if (n == 1LL){
                printf("%lld
    ", f1 % mod);
                continue;
            }
    
            if (n == 2LL){
                printf("%lld
    ", f2 % mod);
                continue;
            }
    
            if (n == 3LL){
                printf("%lld
    ", f3 % mod);
                continue;
            }
    
            LL num = (2 * mod - m) % mod;
    
            init.arr[1][1] = f3, init.arr[1][2] = init.arr[2][1] = f2, init.arr[2][2] = f1;
            unit.arr[1][1] = m + 1, unit.arr[1][2] = num, unit.arr[2][1] = 1, unit.arr[2][2] = 0;
            Matrix mul = MatrixPow(unit, n - 3);
            Matrix ret = Mul(mul, init);
            printf("%lld
    ", ret.arr[1][1]);
        }
    
    
    
        return 0;
    }
    
  • 相关阅读:
    移动端 异常捕获
    禁止选中网页的某段文字
    Java正则表达式的解释说明
    error while performing database login with the xxx driver
    javascript 日期转换为中文
    chrono使用
    resize
    github使用
    adb 无法连接 CreateProcess failure, error 2 * could not start server *
    opencv-videowriter
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6718887.html
Copyright © 2011-2022 走看看