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

 

      

你可能感兴趣的:(poj)