Matrix Power Series
Time Limit: 3000MS | Memory Limit: 131072K | |
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
题意:给出n,k,m,和n*n矩阵,求矩阵a+a^2+...a^k
题解:
| A E | | A^n E+A+A^2+...A^(n-1) |
| 0 E | 的n次方为 | 0 E |
所以补全A矩阵 即扩大到四倍
求新矩阵A的k+1次方 再将又上角的矩阵减去E即可
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; typedef long long ll; struct matrix{ ll a[125][125]; }; matrix fir,per; ll n,m,k; matrix multi(matrix a,matrix b){//两矩阵相乘 matrix ans; for(ll i=1;i<=2*n;i++){ for(ll j=1;j<=2*n;j++){ ans.a[i][j]=0; for(ll k=1;k<=2*n;k++){ ans.a[i][j]=(a.a[i][k]*b.a[k][j]+ans.a[i][j])%m; } } } return ans; } matrix temp; matrix pows(matrix c,ll k){//矩阵快速幂 temp=per; while(k){ if(k&1){ temp=multi(temp,c); } k=k/2; c=multi(c,c); } return temp; } int main(){ scanf("%lld%lld%lld",&n,&k,&m); ll i,j; for(i=1;i<=n;i++){//左上角 for(j=1;j<=n;j++){ scanf("%lld",&fir.a[i][j]); } } for(i=1;i<=2*n;i++){//单位矩阵 for(j=1;j<=2*n;j++){ per.a[i][j]=(i==j); } } for(i=1;i<=n;i++){//右上角 for(j=n+1;j<=2*n;j++){ fir.a[i][j]=(i==j-n); } } for(i=n+1;i<=2*n;i++){//左下角 for(j=1;j<=n;j++){ fir.a[i][j]=0; } } for(i=n+1;i<=2*n;i++){//右下角 for(j=n+1;j<=2*n;j++){ fir.a[i][j]=(i==j); } } matrix ans=pows(fir,k+1); for(i=1;i<=n;i++){ for(j=n+1;j<=2*n;j++){ if(i==j-n){ ans.a[i][j]-=1; if(ans.a[i][j]<0)ans.a[i][j]+=m;//防止减后为-1 } printf("%lld",ans.a[i][j]); if(j==2*n)printf("\n"); else printf(" "); } } return 0; }