时间限制:1000 ms | 内存限制:65535 KB 难度:4
-
描述
- Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
- The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 10^9) and m (m < 10^4). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order. 输出
- Output the elements of S modulo m in the same way as A is given. 样例输入
-
2 2 4 0 1 1 1
样例输出
-
1 2 2 3
分析:
给出这样一个递推式: S = A + A2 + A3 + … + Ak.让你求s,A是一个矩阵,而k非常大。怎么办呢?
推理发现:Fn = A + A*F(n-1)然后我们可以构造矩阵:
(Fn ,1 ) = (Fn-1 ,1) * (A,0。A,1) = (F1 , 1) * (A,0。A,1)^K-1
那么我们就可以用一个矩阵快速幂了。
模板题目的参考代码:
using namespace std; int M; const long long N = 32*2; long long t,b,c,f1,f2; struct tree //基础矩阵 { long long line,cal; long long a[N+1][N+1]; }; struct Node //构造矩阵 { long long line,cal; long long a[N+1][N+1]; Node(tree x) { line=x.line*2; cal=2*x.cal; for(int i=0;i<x.line*2;i++) { for(int j=0;j<x.cal;j++) { a[i][j]=x.a[i%x.line][j]; } } for(int i=0;i<x.line;i++) for(int j=x.cal;j<x.cal*2;j++) a[i][j]=0; for(int i=x.line;i<2*x.line;i++){ for(int j=x.cal;j<2*x.cal;j++){ if(i==j) a[i][j]=1; else a[i][j]=0; } } } }; Node isit(Node x,long long c) //矩阵初始化 { for(long long i=0;i<N;i++) for(long long j=0;j<N;j++) x.a[i][j]=c; return x; } Node Matlab(Node x,Node s) //矩阵乘法 { Node ans(x); ans.line = x.line,ans.cal = s.cal; ans=isit(ans,0); for(long long i=0;i<x.line;i++) { for(long long j=0;j<x.cal;j++) { for(long long k=0;k<s.cal;k++) { ans.a[i][j] += x.a[i][k]*s.a[k][j]; ans.a[i][j]=(ans.a[i][j])%M; } } } return ans; } Node Fast_Matrax(tree x,long long n) //矩阵快速幂 { Node ans(x),tmp(x); for(int i=0;i<ans.line/2;i++) //chushihua { for(int j=0;j<ans.cal;j++) { ans.a[i][j]=ans.a[i+ans.line/2][j]; //printf("%d ",ans.a[i][j]); } } ans.line/=2; while(n>0) { if(n%2) { ans=Matlab(ans,tmp); } tmp=Matlab(tmp,tmp); n/=2; } return ans; } int main() { int n,k,m; while(~scanf("%d%d%d",&n,&k,&m)) { M=m; tree p; p.line=n,p.cal=n; for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&p.a[i][j]); Node ans=Fast_Matrax(p,k-1); for(int i=0;i<ans.line;i++) { for(int j=0;j<ans.cal/2;j++) printf("%d ",ans.a[i][j]); puts(""); } } return 0; }
XXXXX:ACM GavinPSU$ ./martrix.out 2 3 6 2 2 4 4 6 7 2 2 4 4
关于程序算法艺术与实践更多讨论与交流,敬请关注本博客和新浪微博songzi_tea.
-
输入