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 ≤ 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 the elements of S modulo m in the same way as A is given.
一开始就直接敲得交了一发tle一看k是10……9;然后就得减少循环,
对于k,当k为偶数时(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2);
当k为奇数时(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)+A^k
当k为奇数时按式子写会超时,还得优化,因为上式还求了个A^k;
优化为(A+A^2+....A^K) = (A+...+A^K/2)+A(k/2+1)*(A+...+A^K/2)+A(k/2+1);
然后二分求和即可
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<iomanip> #include<vector> #include<map> #include<queue> #include<algorithm> #include<cmath> #include<stdlib.h> using namespace std; typedef long long ll; int n,m; struct matrix { ll m[35][35]; }; matrix mutil(matrix a,matrix b) { matrix c; memset(c.m,0,sizeof(c.m)); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { for(int k=1;k<=n;k++) { c.m[i][j]+=a.m[i][k]*b.m[k][j]%m; //c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%m; } c.m[i][j]%=m; } } return c; } matrix power(matrix a,int k) { matrix ans; memset(ans.m,0,sizeof(ans.m)); for(int i=1;i<=n;i++) ans.m[i][i]=1; while(k) { if(k&1) { ans=mutil(ans,a); k--; } k>>=1; a=mutil(a,a); } return ans; } matrix add(matrix a,matrix b) { matrix c; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { c.m[i][j]=(a.m[i][j]+b.m[i][j])%m; } } return c; } matrix sum(matrix x,int k) { matrix tmp,y; if(k==1) return x; tmp=sum(x,k/2); if(k&1) { y=power(x,k/2+1); tmp=add(tmp,mutil(y,tmp)); return add(tmp,y); } else { y=power(x,k/2); return add(mutil(y,tmp),tmp); } } int main() { int k,i,j; scanf("%d%d%d",&n,&k,&m); matrix a,res; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { scanf("%lld",&a.m[i][j]); } } res=sum(a,k); for(i=1;i<=n;i++) { for(j=1;j<n;j++) { printf("%lld ",res.m[i][j]); } printf("%lld\n",res.m[i][j]); } }