首页 > 代码库 > poj 3233 矩阵快速幂+YY

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*B13 {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^m29 {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

poj 3233 矩阵快速幂+YY