POJ3735 Training little cats 矩阵快速幂 + 矩阵快速幂优化
有n只猫,每只猫初始石刻没糖果。 进行m次重复的k次操作。
g i 给第i只猫一个糖果
s i j 交换第i只猫和第j只猫的糖果
c i 吃掉第i只猫的所有糖果
m <=1e9 明显是用矩阵快速幂处理。 难点在于建立转移矩阵。
注意到只需对单位矩阵操作。对于n只猫建立 n+1 * 1 的矩阵,多的一行存放 1 用来转移。
g i ,即对单位矩阵 E的第i行第n + 1列 set 为1
s i j 即对单位矩阵的i j 行交换
c i 即对单位矩阵的第i行clear
如此就可以矩阵快速幂了 。
注意到矩阵是稀疏矩阵,考虑优化。
#pragma warning(disable:4996) #include<iostream> #include<algorithm> #include<bitset> #include<tuple> #include<unordered_map> #include<fstream> #include<iomanip> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<list> #include<queue> #include<stack> #include<sstream> #include<cstdio> #include<ctime> #include<cstdlib> #define INF 0x3f3f3f3f #define inf 0x7FFFFFFF #define MOD 998244353 #define moD 1000000003 #define pii pair<int,string> #define eps 1e-8 #define equals(a,b) (fabs(a-b)<eps) #define bug puts("bug") #define re register #define fi first #define se second const int maxn = 1e6 + 5; const double Inf = 10000.0; const double PI = acos(-1.0); typedef long long ll; typedef unsigned long long ull; using namespace std; struct Mat { ll m[105][105]; }; Mat E; ll n, m, k; void init(int n) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) if(i == j) E.m[i][j] = 1; } } Mat mul(const Mat& a, const Mat& b) { Mat c; for (int i = 0; i < n + 1; i++) for (int j = 0; j < n + 1; j++) c.m[i][j] = 0; for (int i = 0; i < n + 1; i++) { for (int k = 0; k < n + 1; k++) { if(a.m[i][k]) for (int j = 0; j < n + 1; j++) c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j] ) ; } } return c; } Mat mult(const Mat& a, const Mat& b) { Mat c; for (int i = 0; i < n + 1; i++) { for (int j = 0; j < 1; j++) { c.m[i][j] = 0; for (int k = 0; k < n + 1; k++) c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j] ) ; } } return c; } Mat ans; Mat base; Mat quickPower(Mat a, ll b) { ans = E; base = a; while (b) { if (b & 1) ans = mul(ans, base); base = mul(base, base); b >>= 1; } return ans; } Mat q; int main() { init(105 + 1); while (scanf("%lld%lld%lld", &n, &m, &k), n || m || k) { Mat s; q = E; char op[3]; int x, y; for (int i = 0; i < k; i++) { scanf("%s", op); if (strcmp(op, "g") == 0) { scanf("%d", &x); Mat tmp = E; tmp.m[x - 1][n] = 1; q = mul(tmp, q); } else if (strcmp(op, "s") == 0) { scanf("%d%d", &x, &y); Mat tmp = E; tmp.m[x - 1][x - 1] = 0; tmp.m[x - 1][y - 1] = 1; tmp.m[y - 1][y - 1] = 0; tmp.m[y - 1][x - 1] = 1; q = mul(tmp, q); } else { scanf("%d", &x); Mat tmp = E; tmp.m[x - 1][x - 1] = 0; q = mul(tmp, q); } } q = quickPower(q, m); for (int i = 0; i < n; i++) s.m[i][0] = 0; s.m[n][0] = 1; q = mult(q, s); for (int i = 0; i < n; i++) printf("%lld ", q.m[i][0]); puts(""); } }