zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    典型分布式系统分析:MapReduce
    linux下如何查看自己都装了什么服务
    docker
    linux的命令操作
    IDEA去除掉虚线,波浪线,和下划线实线的方法
    在linux下安装配置rabbitMQ详细教程
    在linux下安装配置rabbitMQ详细教程
    Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数
    shell之startup
    shell脚本特殊变量($0、$1、$2、 $?、 $# 、$@、 $*)
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9683470.html
Copyright © 2011-2022 走看看