poj 3735 稀疏矩阵矩阵快速幂

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

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

\begin{gather}
\begin{bmatrix}
1 & 0 & 0 & 1 \\
0 & 1 & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
\times
\begin{bmatrix}
x \\
y \\
z \\
1 \\
\end{bmatrix}
=
\begin{bmatrix}
x + 1 \\
y \\
z \\
1\\
\end{bmatrix}
\end{gather}

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

\begin{gather}
\begin{bmatrix}
1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
\times
\begin{bmatrix}
x \\
y \\
z \\
1 \\
\end{bmatrix}
=
\begin{bmatrix}
x \\
0 \\
z \\
1\\
\end{bmatrix}
\end{gather}

交换两行

\begin{gather}
\begin{bmatrix}
0 & 1 & 0 & 0 \\
1 & 0 & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
\times
\begin{bmatrix}
x \\
y \\
z \\
1 \\
\end{bmatrix}
=
\begin{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("\n");
    }
    return 0;
}

 

posted @ 2018-09-20 21:32  xayata  阅读(250)  评论(0编辑  收藏  举报