Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 18578 | Accepted: 7858 |
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 22 3
这题可以用矩阵快速幂做。列方程知道dp[i]=dp[i-1]+A[i],所以可以构造矩阵
【A^i,dp[i-1]】*B=【A^(i+1),dp[i]】
其中B=A E
E E
其中E是单位矩阵。
为了方便,可以使得【A^i,dp[i-1]】补成A^i dp[i-1]
0 1
这样就是求B^(k+1)次了
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<algorithm> using namespace std; typedef long long ll; #define inf 99999999 #define pi acos(-1.0) ll MOD; struct matrix{ ll n,m,i; ll data[80][80]; void init_danwei(){ for(i=0;i<n;i++){ data[i][i]=1; } } }a; matrix multi(matrix &a,matrix &b){ ll i,j,k; matrix temp; temp.n=a.n; temp.m=b.m; for(i=0;i<temp.n;i++){ for(j=0;j<temp.m;j++){ temp.data[i][j]=0; } } for(i=0;i<a.n;i++){ for(k=0;k<a.m;k++){ if(a.data[i][k]>0){ for(j=0;j<b.m;j++){ temp.data[i][j]=(temp.data[i][j]+(a.data[i][k]*b.data[k][j])%MOD )%MOD; } } } } return temp; } matrix fast_mod(matrix &a,ll n){ matrix ans; ans.n=a.n; ans.m=a.m; memset(ans.data,0,sizeof(ans.data)); ans.init_danwei(); while(n>0){ if(n&1)ans=multi(ans,a); a=multi(a,a); n>>=1; } return ans; } int main() { ll n,m,i,j,k; while(scanf("%lld%lld%lld",&n,&k,&MOD)!=EOF) { memset(a.data,0,sizeof(a.data )); for(i=0;i<n;i++){ for(j=0;j<n;j++){ scanf("%lld",&a.data[i][j]); } } a.n=a.m=2*n; for(i=0;i<n;i++){ a.data[i][i+n]=a.data[i+n][i+n]=1; } matrix cnt; cnt=fast_mod(a,k+1); int c; for(i=0;i<n;i++){ int flag=1; for(j=0;j<n;j++){ if(i==j){ cnt.data[i][j+n]--; } if(flag){ flag=0;printf("%lld",(cnt.data[i][j+n]+MOD)%MOD ); } else printf(" %lld",(cnt.data[i][j+n]+MOD)%MOD ); } printf("\n"); } } return 0; }