POJ 3222 Matrix Power Series 【等比矩陣前n項之和(性質 OR 二分?)】
阿新 • • 發佈:2019-02-19
Matrix Power Series
(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.
Time Limit: 3000MS | Memory Limit: 131072K |
Total Submissions: 20879 | Accepted: 8735 |
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
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
題意:求等比矩陣前n項之和對m取餘後的矩陣;
思路:資料量較大,看網上解法有兩種,二分的我寫超時 ,用陣列代替結構體遞迴函式不好寫也沒寫出來,用等比矩陣的性質寫出一種:
令 B= [
[A A]
[0 I]
]
則 B^k = [
[A^k A ... A^k]
[0 I ]
]
由A構造出矩陣B之後直接上模板就行,用結構體寫太麻煩,用陣列寫了;
失誤:這道題寫了好久呀,狀態還可以,希望自己不要著急;
AC程式碼:
#include<cstdio> #include<cstring> typedef long long LL; LL ori[77][77],res[77][77]; LL N,mod; void Mat_mul(LL X[77][77],LL Y[77][77]) { LL Z[77][77]; memset(Z,0,sizeof(Z)); LL i=0,j=0,k=0; for(i=1;i<=N*2;++i) { for(k=1;k<=N*2;++k) { if(X[i][k]) { for(j=1;j<=N*2;++j) { Z[i][j]+=(X[i][k]*Y[k][j])%mod; Z[i][j]%=mod; } } } } for(i=1;i<=N*2;++i) { for(j=1;j<=N*2;++j) X[i][j]=Z[i][j]; } } void Mat_Q(LL m) { LL i=0; memset(res,0,sizeof(res)); for(i=1;i<=2*N;++i) res[i][i]=1; while(m) { if(m&1) Mat_mul(res,ori); Mat_mul(ori,ori); m>>=1; } } int main() { LL K,i,j; scanf("%lld %lld %lld",&N,&K,&mod); memset(ori,0,sizeof(ori)); for(i=1;i<=N;++i) { for(j=1;j<=N;++j) { scanf("%lld",&ori[i][j]); ori[i][j+N]=ori[i][j]; } } for(i=N+1;i<=N*2;++i) ori[i][i]=1; Mat_Q(K); for(i=1;i<=N;++i) { for(j=N+1;j<=N*2-1;++j) printf("%lld ",res[i][j]); printf("%lld\n",res[i][2*N]); } return 0; }