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 }
原文地址:https://www.cnblogs.com/Missa/p/2908742.html