# 本博客现已全部转移到新地址，欲获取更多精彩文章，请访问http://acshiryu.github.io/

## poj3233 又见矩阵，不过是等比吗？

Matrix Power Series
 Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 7775 Accepted: 3364

Description

Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.

Input

The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.

Output

Output the elements of S modulo m in the same way as A is given.

Sample Input

2 2 4
0 1
1 1

Sample Output

1 2
2 3

Sk = A + A2 + A3 + … + Ak

=(1+Ak/2)*(A + A2 + A3 + … + Ak/2  )+{Ak}

=(1+Ak/2)*(Sk/2 )+{Ak}

 1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 using namespace std; 8 int n , m ; 9 struct matrix {//矩阵10     int a[30][30];11     void init(  )12     {//初始化13         int i ;14         memset ( a, 0 ,sizeof ( a ) ) ;15         for ( i = 0 ; i < 30 ; i ++ )16             a[i][i] = 1 ;17     }18 };19 void print ( matrix s )20 {//打印一个矩阵21     int i , j ;22     for ( i = 0 ; i < n ; i ++ )23     {24         for ( j = 0 ; j < n ; j ++ )25         {26             if ( j )27                 cout<<' ';28             cout<<s.a[i][j]%m;29         }30         cout<<endl;31     }32 }33 matrix matrixadd ( matrix a , matrix b )34 {//矩阵加法，计算时记得要取模，避免超int35     int i , j ;36     matrix c ;37     for ( i = 0 ; i < n ; i ++ )38         for ( j = 0  ; j < n ; j ++ )39             c.a[i][j]=((a.a[i][j]+b.a[i][j])%m);40     return c ;41 }42 matrix matrixmul ( matrix a , matrix b )43 {//矩阵乘法，计算时记得要取模，避免超int44     int i , j , k ;45     matrix c ;46     for ( i = 0 ; i < n ; i ++ )47     {48         for ( j = 0 ; j < n ; j ++ )49         {50             c.a[i][j]=0;51             for ( k = 0 ; k < n ; k ++ )52                 c.a[i][j] +=((a.a[i][k]*b.a[k][j])%m) ;53             c.a[i][j] %= m ;54         }55     }56     return c ;57 }58 matrix mul ( matrix s , int k  )59 {//矩阵的k次方，快速幂60     matrix ans ;61     ans .init () ;62     while ( k >= 1 )63     {64         if ( k & 1 )65             ans = matrixmul ( ans , s ) ;66         k = k >> 1 ;67         s = matrixmul ( s , s ) ;68     }69     return ans ;70 }71 matrix sum ( matrix s , int k )72 {//举证前k项求和73     if ( k == 1 )74         return s ;75     matrix tmp ;//用来保存答案76     tmp.init();//初始化77     tmp = matrixadd ( tmp , mul ( s , k >> 1 ) );    //计算1+A^(k/2)78     tmp = matrixmul ( tmp , sum ( s , k >> 1 ) ) ;    //计算(1+A^(k/2))*(A + A^2 + A^3 + … + A^(k/2)  )79     if ( k&1 )//考虑是否要+A^k80         tmp = matrixadd ( tmp , mul ( s , k ) ) ;81     return tmp ;//返回前n项的值82 }83 84 int main()85 {86     int k ;87     while ( cin >> n >> k >> m )88     {89         int i , j ;90         matrix s ;91         for ( i = 0 ; i < n ; i ++ )92             for ( j = 0 ; j < n ; j ++ )93                 cin >> s.a[i][j] ;94         s = sum ( s , k ) ;95         print(s);    96     }97     return 0;98 }

posted on 2011-08-09 11:44  ACShiryu  阅读(2334)  评论(7编辑  收藏  举报