标签:size 观察 ret eof pac long ... cal 开始
题意:
给你一个N*K的矩阵A和一个K*N的矩阵B,设矩阵C=AB,M=C^(N*N),矩阵Mmod6后,所有数的和是多少
思路:
刚开始我是直接计算的,开了一个1000*1000的矩阵,结果直接爆掉了
后来看了看题解,发现想的很巧妙
观察 M=ABABAB....AB,AB每次都是1000*1000,可是BA确是6*6的
那么 M=A(BABABA..BA)B,我们让BA进行矩阵快速幂就不会爆掉了
M=A(BA)^(N*N-1)B,最后计算一下就好了
代码:
#include <iostream> #include <algorithm> #include <cstdio> #include <cmath> #include <cstring> #define ll long long #define mod 6 using namespace std; int n,k; struct Matrix { ll m[6][6]; }; Matrix I; Matrix multi(Matrix a,Matrix b) { Matrix ans; for(int i=0;i<k;i++) { for(int j=0;j<k;j++) { ans.m[i][j]=0; for(int p=0;p<k;p++) { ans.m[i][j]+=(a.m[i][p]*b.m[p][j])%mod; } ans.m[i][j]%=mod; } } return ans; } Matrix power(Matrix a,ll b) { Matrix ans=I; while(b) { if(b&1) { ans=multi(ans,a); } b=b/2; a=multi(a,a); } return ans; } ll A[1005][1005]; ll B[1005][1005]; Matrix BA; ll tmp[1005][1005]; ll ans[1005][1005]; int main() { while(cin>>n>>k) { if(n==0&&k==0) break; for(int i=0;i<n;i++) { for(int j=0;j<k;j++) { scanf("%lld",&A[i][j]); } } for(int i=0;i<k;i++) { for(int j=0;j<n;j++) { scanf("%lld",&B[i][j]); } } for(int i=0;i<k;i++) { for(int j=0;j<k;j++) { BA.m[i][j]=0; for(int p=0;p<n;p++) { BA.m[i][j]+=(B[i][p]*A[p][j])%mod; } BA.m[i][j]%=mod; } } memset(I.m,0,sizeof(I.m)); for(int i=0;i<k;i++) I.m[i][i]=1; BA=power(BA,n*n-1); for(int i=0;i<n;i++) { for(int j=0;j<k;j++) { tmp[i][j]=0; for(int p=0;p<k;p++) { tmp[i][j]+=(A[i][p]*BA.m[p][j])%mod; } tmp[i][j]%=mod; } } ll num=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { ans[i][j]=0; for(int p=0;p<k;p++) { ans[i][j]+=(tmp[i][p]*B[p][j])%mod; } ans[i][j]%=mod; num=num+ans[i][j]; } } cout<<num<<endl; } return 0; }
hdu 4965 Fast Matrix Calculation(矩阵快速幂)
标签:size 观察 ret eof pac long ... cal 开始
原文地址:http://www.cnblogs.com/simplekinght/p/7087276.html