Matrix Power Series
Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 20210 | Accepted: 8478 |
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
Source
POJ Monthly--2007.06.03, Huang, Jinsong
解法有多种。
1.利用分块矩阵
思路比较简单,建立下面分块矩阵,
各个分块矩阵都是m*m的,I表示单位矩阵,O表示零矩阵,可以将它变化为幂次形式,即,
1 #include <iostream> 2 #include <algorithm> 3 #include <map> 4 #include <vector> 5 #include <functional> 6 #include <string> 7 #include <cstring> 8 #include <queue> 9 #include <set> 10 #include <cmath> 11 #include <cstdio> 12 using namespace std; 13 #define IOS ios_base::sync_with_stdio(false)] 14 typedef long long LL; 15 const int INF=0x3f3f3f3f; 16 17 const int maxn=61; 18 int modnum, n,k; 19 typedef struct matrix{ 20 int v[maxn][maxn]; 21 void init(){memset(v,0,sizeof(v));} 22 }M; 23 M a,b,a2,d,r; 24 M mul_mod(const M &a,const M &b,int L,int m,int n) 25 { 26 M c; c.init(); 27 for(int i=0;i<L;i++){ 28 for(int j=0;j<n;j++){ 29 for(int k=0;k<m;k++)//注意j,k范围 30 c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j]%modnum)%modnum; 31 } 32 } 33 return c; 34 } 35 M power(M x,int L,int p) 36 { 37 M tmp; tmp.init(); 38 for(int i=0;i<L;i++) 39 tmp.v[i][i]=1; 40 while(p){ 41 if(p&1) tmp=mul_mod(x,tmp,L,L,L); 42 x=mul_mod(x,x,L,L,L); 43 p>>=1; 44 } 45 return tmp; 46 } 47 void init() 48 { 49 b.init(); 50 for(int i=0;i<n;i++) 51 b.v[i][i]=b.v[i][i+n]=1; 52 for(int i=n;i<2*n;i++) 53 for(int j=n;j<2*n;j++) 54 b.v[i][j]=d.v[i%n][j%n]=a.v[i%n][j%n]; 55 a2=power(a,n,2); 56 for(int i=n;i<2*n;i++) 57 for(int j=0;j<n;j++) 58 d.v[i][j]=a2.v[i%n][j]; 59 } 60 61 int main() 62 { 63 while(scanf("%d%d%d",&n,&k,&modnum)==3){ 64 for(int i=0;i<n;i++){ 65 for(int j=0;j<n;j++){ 66 scanf("%d",&a.v[i][j]); 67 a.v[i][j]%=modnum; 68 } 69 } 70 if(k==1){ 71 for(int i=0;i<n;i++){ 72 for(int j=0;j<n;j++) 73 printf("%d ",a.v[i][j]); 74 printf(" "); 75 } 76 continue; 77 } 78 init(); 79 r=power(b,2*n,k-1); 80 r=mul_mod(r,d,2*n,2*n,n); 81 for(int i=0;i<n;i++){ 82 for(int j=0;j<n;j++) 83 printf("%d ",r.v[i][j]); 84 printf(" "); 85 } 86 } 87 }