• poj 3735 稀疏矩阵矩阵快速幂


    设人数为 $n$,构造 $(n + 1) imes (n + 1)$ 的矩阵

    得花生:
    将改行的最后一列元素 $+ 1$

    egin{gather}
    egin{bmatrix}
    1 & 0 & 0 & 1 \
    0 & 1 & 0 & 0 \
    0 & 0 & 1 & 0 \
    0 & 0 & 0 & 1
    end{bmatrix}
    imes
    egin{bmatrix}
    x \
    y \
    z \
    1 \
    end{bmatrix}
    =
    egin{bmatrix}
    x + 1 \
    y \
    z \
    1\
    end{bmatrix}
    end{gather}

    吃花生:
    将一行的元素全部清零

    egin{gather}
    egin{bmatrix}
    1 & 0 & 0 & 0\
    0 & 0 & 0 & 0 \
    0 & 0 & 1 & 0 \
    0 & 0 & 0 & 1
    end{bmatrix}
    imes
    egin{bmatrix}
    x \
    y \
    z \
    1 \
    end{bmatrix}
    =
    egin{bmatrix}
    x \
    0 \
    z \
    1\
    end{bmatrix}
    end{gather}

    交换两行

    egin{gather}
    egin{bmatrix}
    0 & 1 & 0 & 0 \
    1 & 0 & 0 & 0 \
    0 & 0 & 1 & 0 \
    0 & 0 & 0 & 1
    end{bmatrix}
    imes
    egin{bmatrix}
    x \
    y \
    z \
    1 \
    end{bmatrix}
    =
    egin{bmatrix}
    y \
    x \
    z \
    1\
    end{bmatrix}
    end{gather}

    普通矩阵快速幂
    TLE
    稀疏矩阵矩阵快速幂

    #include <iostream>
    #include <cstdio>
    #include <algorithm> 
    #include <cstring>
    
    using namespace std;
    const int N = 110;
    
    #define LL long long
    
    LL n, m, k;
    struct Matrix {LL M[N][N];} A;
    
    Matrix operator * (Matrix &a, Matrix &b) {
        Matrix ret;
        memset(ret.M, 0, sizeof ret.M);
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= n; j ++)
                if(a.M[i][j]) 
                    for(int K = 1; K <= n; K ++)
                        ret.M[i][K] = (ret.M[i][K] + a.M[i][j] * b.M[j][K]);
        return ret;
    }
    
    
    
    Matrix Ksm(int p) {
        Matrix Ans;
        memset(Ans.M, 0, sizeof Ans.M);
        for(int i = 1; i <= n; i ++) Ans.M[i][i] = 1;
        while(p) {
            if(p & 1) Ans = Ans * A;
            A = A * A;
            p >>= 1;
        }
        return Ans;
    }
    
    int main() {
        while(1) {
            cin >> n >> k >> m;
            if(n == 0 && m == 0 && k == 0) return 0;
            n ++;
            char s[10];
            memset(A.M, 0, sizeof A.M);
            for(int i = 1; i <= n; i ++) A.M[i][i] = 1;
            for(int i = 1; i <= m; i ++) {
                scanf("%s", s);
                if(s[0] == 'g') {
                    int x; std:: cin >> x;
                    A.M[x][n] ++;
                } else if(s[0] == 'e') {
                    int x; std:: cin >> x;
                    for(int j = 1; j <= n; j ++) A.M[x][j] = 0;
                } else {
                    int x, y; std:: cin >> x >> y;
                    swap(A.M[x], A.M[y]);
                }
            }
            Matrix Answer = Ksm(k);
            for(int i = 1; i < n; i ++) cout << Answer.M[i][n] << " ";
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    hash算法
    2020/9/30计算机硬件组成day3
    NIO与IO区别
    Collection.toArray()方法使用的坑&如何反转数组
    Arrays.asList()使用指南
    JDK8的LocalDateTime用法
    Linux 删除文件夹和文件的命令
    list集合为空或为null的区别
    easyExcel使用
    java Object 转换为 Long
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9683470.html
Copyright © 2020-2023  润新知