如果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
然后二分求解即可。思路简单。
接下来说一下优化的问题:
-------------------------------TLE
G++的耗时比C++小。-2391MS
闲着没事不要初始化。-1782MS
尽量减小取余的次数。-1125MS
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; #define Nnum 31 #define Mnum 31 #define LL long long struct matrix { int mat[31][31]; }; int n,m; matrix ONE; matrix mul(matrix A,matrix B)//矩阵相乘 { int i,j,k; matrix C; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { C.mat[i][j]=0; for(k=1;k<=n;k++) { C.mat[i][j]=(A.mat[i][k]*B.mat[k][j]+C.mat[i][j])%m; } } } return C; } matrix add(matrix A,matrix B)//矩阵相加 { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { A.mat[i][j]+=B.mat[i][j]; A.mat[i][j]=A.mat[i][j]%m; } } return A; } matrix powmul(matrix A,int k)//A矩阵的k次方 { if(k==1)return A; matrix B=powmul(A,k/2); B=mul(B,B); if(k%2)B=mul(B,A); return B; } matrix dos(matrix A,int k) { if(k==1)return A; if(k%2==0) { matrix B=dos(A,k/2); return mul(add(powmul(A,k/2),ONE),B); } else { matrix B=dos(A,(k)/2); matrix C=powmul(A,(k+1)/2); return add(C,mul(B,add(C,ONE))); } } int main() { int k,i,j; matrix A; scanf("%d%d%d",&n,&k,&m); for(i=1;i<=n;i++) { ONE.mat[i][i]=1; for(j=1;j<=n;j++) { scanf("%d",&A.mat[i][j]); } } matrix ans=dos(A,k); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(j!=1)cout<<" "; printf("%d",(ans.mat[i][j])%m); } cout<<endl; } return 0; }
矩阵十大经典题目之三-POJ-3233-Matrix Power Series-两次二分,布布扣,bubuko.com
矩阵十大经典题目之三-POJ-3233-Matrix Power Series-两次二分
原文:http://blog.csdn.net/rowanhaoa/article/details/21023599