矩阵快速幂 POJ 3735 Training little cats

题目传送门

 1 /*
 2     题意:k次操作,g:i猫+1, e:i猫eat,s:swap
 3     矩阵快速幂:写个转置矩阵,将k次操作写在第0行,定义A = {1,0, 0, 0...}除了第一个外其他是猫的初始值
 4         自己讲太麻烦了,网上有人讲的很清楚,膜拜之
 5     详细解释:http://www.cppblog.com/y346491470/articles/157284.html
 6 */
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <cmath>
10 #include <algorithm>
11 using namespace std;
12 
13 typedef long long ll;
14 const int MAXN = 1e2 + 10;
15 const int INF = 0x3f3f3f3f;
16 struct Mat  {
17     ll m[MAXN][MAXN];
18     Mat ()  {
19         memset (m, 0, sizeof (m));
20     }
21     void init(void) {
22         for (int i=0; i<MAXN; ++i)  m[i][i] = 1;
23     }
24 };
25 int n, m, k;
26 
27 Mat operator * (Mat &a, Mat &b) {
28     Mat ret;
29     for (int k=0; k<=n; ++k)    {
30         for (int i=0; i<=n; ++i)    {
31             if (a.m[i][k])  {
32                 for (int j=0; j<=n; ++j)    {
33                     ret.m[i][j] += a.m[i][k] * b.m[k][j];
34                 }
35             }
36         }
37     }
38     return ret;
39 }
40 
41 Mat operator ^ (Mat x, int n)   {
42     Mat ret;    ret.init ();
43     while (n)   {
44         if (n & 1)  ret = ret * x;
45         x = x * x;
46         n >>= 1;
47     }
48     return ret;
49 }
50 
51 int main(void)  {       //POJ 3735 Training little cats
52     while (scanf ("%d%d%d", &n, &m, &k) == 3)   {
53         if (!n && !m && !k) break;
54         Mat A, T;   A.m[0][0] = 1;  T.init ();
55         char op[5]; int p, q;
56         while (k--) {
57             scanf ("%s", op);
58             if (op[0] == 'g')    {
59                 scanf ("%d", &p);   T.m[0][p]++;
60             }
61             else if (op[0] == 'e')  {
62                 scanf ("%d", &p);
63                 for (int i=0; i<=n; ++i)    T.m[i][p] = 0;
64             }
65             else    {
66                 scanf ("%d%d", &p, &q);
67                 for (int i=0; i<=n; ++i)    swap (T.m[i][p], T.m[i][q]);
68             }
69         }
70         Mat ans = A * (T ^ m);
71         for (int i=1; i<=n; ++i)    printf ("%I64d%c", ans.m[0][i], (i==n) ? '
' : ' ');
72     }
73 
74     return 0;
75 }
编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4693075.html