Matrix Power Series
Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 19132 | Accepted: 8070 |
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
思路:运用数学二分
对k进行二分,每次将规模减半,分k为奇偶两种情况,如当k = 6和k = 7时有:k = 6 有: S(6) = (1 + A^3) * (A + A^2 + A^3) = (1 + A^3) * S(3)。 k = 7 有: S(7) = A + (A + A^4) * (A + A^2 + A^3) = A + (A + A^4) * S(3)。 #include<stdio.h> #include<string.h> #include<algorithm> #define INF 0x3f3f3f3f #define ll long long #define N 50 using namespace std; struct mat { ll m[N][N]; }; int n,k,M; mat matadd(mat a,mat b)//矩阵相加 { int i,j; mat c; for(i=0;i<n;i++) { for(j=0;j<n;j++) { c.m[i][j]=(a.m[i][j]+b.m[i][j])%M; } } return c; } mat multi(mat a,mat b)//矩阵相乘 { int i,j,k; mat c; for(i=0;i<n;i++) { for(j=0;j<n;j++) { c.m[i][j]=0; for(k=0;k<n;k++) { c.m[i][j]=(a.m[i][k]*b.m[k][j]+c.m[i][j])%M; } } } return c; } mat power(mat A,int k)//矩阵快速幂 { if(!k) { memset(A.m,0,sizeof(A.m)); for(int i=0;i<n;i++) A.m[i][i]=1; return A; } if(k==1) return A; mat c=power(A,k/2); if(k%2==0) return multi(c,c); else return multi(multi(c,c),A); } mat matcal(mat A,int k)// 求S (k) = A + A2 + A3 + … + Ak { if(k==1) return A; mat b=power(A,(k+1)/2); mat c=matcal(A,k/2); if(k%2==0) return multi(matadd(power(A,0),b),c);// 如S(6) = (1 + A^3) * S(3) else return matadd(A,multi(matadd(A,b),c));// 如S(7) = A + (A + A^4) * S(3) } int main() { int i,j; mat A; scanf("%d%d%d",&n,&k,&M); for(i=0;i<n;i++) { for(j=0;j<n;j++) { scanf("%lld",&A.m[i][j]); } } A=matcal(A,k); for(i=0;i<n;i++) { for(j=0;j<n;j++) { printf(j?" %lld":"%lld",A.m[i][j]); } printf("\n"); } return 0; }