poj3735Training little cats

链接

构造矩阵 快速幂求解

构造矩阵a[i]为每个cati所拥有的花生总数 这里多加一维用来求和,具体是怎么求得可以看下面的一组例子 假设有3个cat a[] = {1,0,0,0}

构造单位矩阵来保存操作后的解 为什么要是单位矩阵?因为单位矩阵乘以任何矩阵还是原矩阵 这样在单位矩阵上改变要操作的那列(这里用列来表示i只猫的花生数)就能保留下来不被改变的猫的

花生数

对于g 1

(1,0,0,0)*{1,1,0,0

      0,1,0,0

      0,0,1,0

      0,0,0,1}

这样得出结果(1,1,0,0} 也就是说对于g1 就让mat[0][i]+1就可以了 因为加了k 最后都会变成a[i][i]+a[0][0]*k a[i][i]为前一步的i所拥有的花生数 而a[0][0]始终为1

类似的 对于e 1

就是把第1列清0

s i,j

就把第i,j列互换

这样得出一个k个操作后的矩阵T 求解T^m。

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 102
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 struct Mat
18 {
19     LL mat[N][N];
20 };
21 int n;
22 Mat operator * (Mat a,Mat b)
23 {
24     Mat c;
25     memset(c.mat,0,sizeof(c.mat));
26     int i,j,k;
27     for(k =0 ; k < n ; k++)
28     {
29         for(i = 0 ; i < n ;i++)
30         {
31             if(a.mat[i][k]==0) continue;//优化
32             for(j = 0 ;j < n ;j++)
33             {
34                 if(b.mat[k][j]==0) continue;//优化
35                 c.mat[i][j] += a.mat[i][k]*b.mat[k][j];
36             }
37         }
38     }
39     return c;
40 }
41 Mat operator ^(Mat a,int k)
42 {
43     Mat c;
44     int i,j;
45     for(i =0 ; i < n ;i++)
46         for(j = 0; j < n ;j++)
47         c.mat[i][j] = (i==j);
48     for(; k ;k >>= 1)
49     {
50         if(k&1) c = c*a;
51         a = a*a;
52     }
53     return c;
54 }
55 Mat init()
56 {
57     int i;
58     Mat c;
59     memset(c.mat,0,sizeof(c.mat));
60     for(i = 0 ; i <= n; i++)
61     c.mat[i][i] = 1;
62     return c;
63 }
64 int main()
65 {
66     int i,j,k,m;
67     char s[2];
68     while(cin>>n>>m>>k)
69     {
70         if(!n&&!k&&!m) break;
71         Mat t = init();
72         for(i = 1; i <=k; i++)
73         {
74             int x,y;
75             cin>>s>>x;
76             if(s[0]=='g')
77             t.mat[0][x]++;
78             else if(s[0]=='e')
79             {
80                 for(j = 0; j <= n ;j++)
81                 t.mat[j][x] = 0;
82             }
83             else
84             {
85                 cin>>y;
86                 for(j =0 ; j <= n; j++)
87                 swap(t.mat[j][x],t.mat[j][y]);
88             }
89         }
90         n++;
91         t = t^m;
92         for(i =1 ;i < n-1; i++)
93         cout<<t.mat[0][i]<<" ";
94         cout<<t.mat[0][n-1]<<endl;
95     }
96     return 0;
97 }
View Code

      

原文地址:https://www.cnblogs.com/shangyu/p/3621036.html