设人数为 $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; }
原文地址:https://www.cnblogs.com/shandongs1/p/9683470.html