poj 3735 (矩阵快速幂)

题意:有n只猫咪,开始时每只猫咪有花生0颗,现有一组操作,由下面三个中的k个操作组成:
               1. g i 给i只猫咪一颗花生米
               2. e i 让第i只猫咪吃掉它拥有的所有花生米
               3. s i j 将猫咪i与猫咪j的拥有的花生米交换

               现将上述一组操作做m次后,问每只猫咪有多少颗花生?

解题报告:http://www.cnblogs.com/acSzz/archive/2012/08/20/2648087.html

View Code
  1 // File Name: 3735.cpp

  2 // Author: Missa

  3 // Created Time: 2013/2/7 星期四 12:35:55

  4 

  5 #include<iostream>

  6 #include<cstdio>

  7 #include<cstring>

  8 #include<algorithm>

  9 #include<cmath>

 10 #include<queue>

 11 #include<stack>

 12 #include<string>

 13 #include<vector>

 14 #include<cstdlib>

 15 #include<map>

 16 using namespace std;

 17 #define ll long long

 18 ll n,m,k;

 19 //**********矩阵快速幂********************

 20 const int maxn=105;//矩阵最大范围

 21 //int n,m;//矩阵n*m

 22 struct Mat

 23 {

 24     ll mat[maxn][maxn];

 25     void clear()

 26     {

 27         memset(mat,0,sizeof(mat));

 28     }

 29     void unit()//单元矩阵n*n矩阵的时候需要

 30     {

 31         clear();

 32         for(int i=0;i<=n;i++)

 33             mat[i][i]=1;

 34     }

 35 };

 36 Mat a;

 37 void init()

 38 {

 39     a.unit();

 40 }

 41 Mat mul(Mat a,Mat b)

 42 {

 43     Mat c;

 44     c.clear();

 45     for(int i=0;i<=n;i++)//n+1 * n+1 的矩阵

 46     {

 47         for(int k=0;k<=n;k++)

 48         {

 49             if(a.mat[i][k])

 50             {

 51                 for(int j=0;j<=n;j++)

 52                     c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];

 53             }

 54         }

 55     }

 56     return c;

 57 }

 58 Mat mpow(Mat a,ll k)//非递归实现

 59 {

 60     if(k==1) return a;

 61     Mat e;

 62     e.unit();

 63     while(k)

 64     {

 65         if(k&1)     e=mul(e,a);

 66         k>>=1;

 67         a=mul(a,a);

 68     }

 69     return e;

 70 }

 71 //***********矩阵快速幂*******************

 72 

 73 int main()

 74 {

 75     while(~scanf("%lld%lld%lld",&n,&m,&k))

 76     {

 77         if(!n && !m && !k) break;

 78         init();

 79         while(k--)

 80         {

 81             ll x,y;

 82             char o[10];

 83             scanf("%s",&o);

 84             if(o[0]=='g')

 85             {

 86                 scanf("%lld",&x);

 87                 a.mat[0][x]++;

 88             }

 89             else if(o[0]=='e')

 90             {

 91                 scanf("%lld",&x);

 92                 for(int i=0;i<=n;i++)

 93                     a.mat[i][x]=0;

 94             }

 95             else

 96             {

 97                 scanf("%lld%lld",&x,&y);

 98                 for(int i=0;i<=n;i++)

 99                     swap(a.mat[i][x],a.mat[i][y]);

100             }

101         }

102         if(m==0)

103         {

104             printf("0");

105             for(int i=2;i<=n;i++)

106                 printf(" 0");

107             printf("\n");

108             continue;

109         }

110         a=mpow(a,m);

111         printf("%lld",a.mat[0][1]);

112         for(int i=2;i<=n;i++)

113             printf(" %lld",a.mat[0][i]);

114         printf("\n");

115     }

116     return 0;

117 }

 

你可能感兴趣的:(poj)