poj 3233 矩阵快速幂+YY
题意:给你矩阵A,求S=A+A^1+A^2+...+A^n
sol:直接把每一项解出来显然是不行的,也没必要。
我们可以YY一个矩阵:
其中1表示单位矩阵
然后容易得到:
可以看出这个分块矩阵的左下角那块就可以得到要求的解S
我们取这一块,再减去一个单位矩阵1即可。
1 #include "iostream" 2 #include "vector" 3 #include "cstring" 4 #include "cstdio" 5 using namespace std; 6 7 //typedef unsigned long int ULL; 8 typedef vector<int> vec; 9 typedef vector<vec> mat; 10 int n,m,k,P; 11 12 mat mul(mat &A,mat &B) //return A*B 13 { 14 mat C(A.size(),vec(B[0].size())); 15 for (int i=0;i<(int)A.size();i++) 16 { 17 for (int k=0;k<(int)B.size();k++) 18 { 19 for (int j=0;j<(int)B[0].size();j++) 20 { 21 C[i][j]=(C[i][j]+A[i][k]*B[k][j])%P; 22 } 23 } 24 } 25 return C; 26 } 27 28 mat m_pow(mat A,int m) //return A^m 29 { 30 mat B(A.size(),vec(A.size())); 31 for (int i=0;i<(int)A.size();i++) 32 B[i][i]=1; 33 while (m>0) 34 { 35 if (m&1) B=mul(B,A); 36 A=mul(A,A); 37 m>>=1; 38 } 39 return B; 40 } 41 42 int main() 43 { 44 //freopen("in.txt","r",stdin); 45 46 cin>>n>>k>>P; 47 mat A(2*n,vec(2*n)); 48 49 for (int i=0;i<n;i++) 50 for (int j=0;j<n;j++) 51 cin>>A[i][j]; 52 for (int i=n;i<=2*n-1;i++) 53 { 54 A[i][i-n]=1; 55 A[i][i]=1; 56 } 57 58 A=m_pow(A,k+1); 59 60 for (int i=n;i<2*n;i++) 61 { 62 for (int j=0;j<n;j++) 63 { 64 if (i==j+n) 65 A[i][j]--; 66 if (A[i][j]<0) A[i][j]+=P; 67 cout<<A[i][j]<<" "; 68 } 69 cout<<endl; 70 } 71 return 0; 72 }
注意:挑战程序设计那本书P205上取了左上角那块,估计是写错了orz
----------------------------
本题还有一种方法,reference: http://www.cnblogs.com/ACShiryu/archive/2011/08/09/poj3233.html
posted on 2014-10-30 21:02 Pentium.Labs 阅读(570) 评论(0) 编辑 收藏 举报