zoukankan      html  css  js  c++  java
  • AcWing

    https://www.acwing.com/problem/content/submission/227/

    需要构造一种新的矩阵,受到前几天xy的求和的启发,但是还是不知道矩阵的求和怎么搞。事实上矩阵的求和是一样的。

    构造一个矩阵:其中E是单位矩阵,O是零矩阵,那么这个东西转移n次就得到需要的Sn,而A在此过程中自动转移。

    [left[ egin{matrix} S_1 \ A^2 \ end{matrix} ight] = left[ egin{matrix} E&E \ O&A \ end{matrix} ight] * left[ egin{matrix} S_0 \ A^1 \ end{matrix} ight] ]

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int mod;
    struct Matrix30 {
        static const int MAXN = 30;
        int ma[MAXN][MAXN];
        Matrix30 () {
            init();
        }
        void init() {
            memset(ma, 0, sizeof(ma));
        }
        void setE() {
            init();
            for(int i = 0; i < MAXN; ++i)
                ma[i][i] = 1;
        }
        Matrix30 operator+(const Matrix30 &m)const {
            Matrix30 Tmp;
            Tmp.init();
            for(int i = 0; i < MAXN; ++i) {
                for(int j = 0; j < MAXN; ++j)
                    Tmp.ma[i][j] += (ma[i][j] + m.ma[i][j]) % mod;
            }
            for(int i = 0; i < MAXN; ++i) {
                for(int j = 0; j < MAXN; ++j)
                    if(Tmp.ma[i][j] >= mod)
                        Tmp.ma[i][j] %= mod;
            }
            return Tmp;
        }
    
        Matrix30 operator*(const Matrix30 &m)const {
            Matrix30 Tmp;
            Tmp.init();
            for(int k = 0; k < MAXN; ++k) {
                for(int i = 0; i < MAXN; ++i) {
                    register int r = ma[i][k];
                    for(int j = 0; j < MAXN; ++j)
                        Tmp.ma[i][j] += (r * m.ma[k][j]) % mod;
                }
            }
            for(int i = 0; i < MAXN; ++i) {
                for(int j = 0; j < MAXN; ++j)
                    if(Tmp.ma[i][j] >= mod)
                        Tmp.ma[i][j] %= mod;
            }
            return Tmp;
        }
        void show(int n) {
            for(int i = 0; i < n; ++i) {
                for(int j = 0; j < n; ++j)
                    printf("%d%c", ma[i][j], " 
    "[j == n - 1]);
            }
        }
    } E, O, A;
    
    struct Matrix2 {
        static const int MAXN = 2;
        Matrix30 ma[MAXN][MAXN];
        Matrix2 () {
            init();
        }
        void init() {
            ma[0][0] = O;
            ma[0][1] = O;
            ma[1][0] = O;
            ma[1][1] = O;
        }
        void setE() {
            ma[0][0] = E;
            ma[0][1] = O;
            ma[1][0] = O;
            ma[1][1] = E;
        }
        Matrix2 operator*(const Matrix2 &m)const {
            Matrix2 Tmp;
            Tmp.init();
            for(int k = 0; k < MAXN; ++k) {
                for(int i = 0; i < MAXN; ++i)
                    for(int j = 0; j < MAXN; ++j)
                        Tmp.ma[i][j] = Tmp.ma[i][j] + (ma[i][k] * m.ma[k][j]);
            }
            return Tmp;
        }
    };
    
    Matrix2 qpow(Matrix2 x, int n) {
        Matrix2 res;
        res.setE();
        while(n) {
            if(n & 1)
                res = res * x;
            x = x * x;
            n >>= 1;
        }
        return res;
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        int n, k;
        scanf("%d%d%d", &n, &k, &mod);
        E.setE();
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < n; ++j) {
                scanf("%d", &A.ma[i][j]);
                A.ma[i][j] %= mod;
            }
        }
    
        Matrix2 NXT;
        NXT.ma[0][0] = E;
        NXT.ma[0][1] = E;
        NXT.ma[1][0] = O;
        NXT.ma[1][1] = A;
    
        Matrix2 I;
        I.ma[0][0] = O;
        I.ma[0][1] = O;
        I.ma[1][0] = A;
        I.ma[1][1] = O;
    
        Matrix2 RES = qpow(NXT, k);
        RES = RES * I;
        RES.ma[0][0].show(n);
    }
    
  • 相关阅读:
    成为java程序员的学习过程
    解决自动添加局域网内打印机的问题
    通过主机标头实现多个SharePoint Web应用程序共用一个端口
    MSDN教学短片WPF 3(WPF的图形透明效果)
    MSDN 教学短片 WPF 14(2D动画之—Trigger)
    MSDN 教程短片 WPF 8(WPF样式与资源)
    MSDN 教学短片WPF 5(Linear/RadialGradientBrush)
    MSDN 教学短片 WPF 12(画布)
    MSDN 教学短片WPF 4(笔刷)
    MSDN 教程短片 WPF 17(简单播放器的制作)
  • 原文地址:https://www.cnblogs.com/Inko/p/11528612.html
Copyright © 2011-2022 走看看