设人数为 $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; }