蒟蒻萌新求助,矩阵写法,subtask1最后一个点RE
查看原帖
蒟蒻萌新求助,矩阵写法,subtask1最后一个点RE
512729
Kenshin2438楼主2021/8/24 17:06

矩阵写法,不知道为什么subtask1最后一个RE了。

思路是矩阵快速幂+拓展欧拉定理。

求数据。

#include <cstdio>
typedef long long i64;

struct Matrix {
    int mat[2][2];
    Matrix() {mat[0][0] = mat[1][1] = 1, mat[1][0] = mat[0][1] = 0;}
    void setBase() {mat[0][0] = mat[0][1] = mat[1][0] = 1, mat[1][1] = 0;}
    void operator *= (const Matrix &x) {
        Matrix res;
        for (int i = 0; i < 2; i++) 
            for (int j = 0; j < 2; j++) {
                res.mat[i][j] = 0;
                for (int k = 0; k < 2; k++) 
                    res.mat[i][j] += mat[i][k] * x.mat[k][j];
            }
        *this = res;
    }
    void operator %= (const int &mod) {
        mat[0][0] %= mod, mat[0][1] %= mod, mat[1][0] %= mod, mat[1][1] %= mod;
    }
    void pw(i64 n) {
        Matrix res, x;
        for (x.setBase(); n; n >>= 1, x *= x)
            if (n & 1) res *= x;
        *this = res;
    }
    void modpw(i64 n, int mod) {
        Matrix res, x;
        for (x.setBase(); n; n >>= 1, x *= x, x %= mod)
            if (n & 1) res *= x, res %= mod;
        *this = res;
    }
} F;

inline int qpow(int x, int n, int mod, int res = 1) {
    for (x %= mod; n; n >>= 1, x = x * x % mod)
        if (n & 1) res = res * x % mod;
    return res; 
}

int main() {
    int n, m; i64 k; scanf("%d%d%lld", &n, &m, &k);
    if (k == 1LL) return printf("%d", n);
    if (k == 2LL) return printf("%d", m);
    if (k <= 8) {
        F.pw(k - 1);
        printf("%d", qpow(n, F.mat[1][1], 10) * qpow(m, F.mat[1][0], 10) % 10);
    } else {
        F.modpw(k - 1, 4);
        printf("%d", qpow(n, F.mat[1][1] + 4, 10) * qpow(m, F.mat[1][0] + 4, 10) % 10);
    }
    return 0;
}
2021/8/24 17:06
加载中...