题目链接:http://poj.org/problem?id=3233
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
解题思路:等比矩阵求和,参考了一下别人的写法,链接:poj3233 又见矩阵,不过是等比吗?;不错,求前k项和用递归比较好理解。
AC代码:
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int maxn=35; 5 int n,k,mod; 6 struct Matrix 7 { 8 int m[maxn][maxn]; 9 }init; 10 Matrix add(Matrix a,Matrix b){//两个矩阵相加 11 Matrix c; 12 for(int i=0;i<n;++i) 13 for(int j=0;j<n;++j) 14 c.m[i][j]=(a.m[i][j]+b.m[i][j])%mod; 15 return c; 16 } 17 Matrix mul(Matrix a,Matrix b)//两个矩阵相乘 18 { 19 Matrix c; 20 for(int i=0;i<n;i++){ 21 for(int j=0;j<n;j++){ 22 c.m[i][j]=0; 23 for(int k=0;k<n;k++) 24 c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j]%mod)%mod; 25 c.m[i][j]%=mod; 26 } 27 } 28 return c; 29 } 30 Matrix POW(Matrix a,int x)//矩阵快速幂 31 { 32 Matrix b; 33 memset(b.m,0,sizeof(b.m)); 34 for(int i=0;i<n;++i)b.m[i][i]=1;//单位矩阵 35 while(x){ 36 if(x&1)b=mul(b,a); 37 a=mul(a,a); 38 x>>=1; 39 } 40 return b; 41 } 42 Matrix sum(Matrix s,int k){//求前k项和 43 if(k==1)return s;//递归出口,如果幂指数为1,返回当前矩阵 44 Matrix tmp;//用来保存答案 45 memset(tmp.m,0,sizeof(tmp.m)); 46 for(int i=0;i<n;++i)tmp.m[i][i]=1;//单位矩阵 47 tmp=add(tmp,POW(s,k>>1));//计算1+A^(k/2) 48 tmp=mul(tmp,sum(s,k>>1));//计算(1+A^(k/2))*(A + A^2 + A^3 + … + A^(k/2))=(1+A^(k/2))*(Sk/2) 49 if(k&1)tmp=add(tmp,POW(s,k));//若k是奇数,则加上A^k 50 return tmp;//返回前k项的值 51 } 52 void print_rectangle(Matrix r){ 53 for(int i=0;i<n;++i) 54 for(int j=0;j<n;++j) 55 cout<<r.m[i][j]<<((j==n-1)?"\n":" "); 56 } 57 int main() 58 { 59 while(cin>>n>>k>>mod){ 60 for(int i=0;i<n;++i) 61 for(int j=0;j<n;++j) 62 cin>>init.m[i][j]; 63 init=sum(init,k); 64 print_rectangle(init); 65 } 66 return 0; 67 }