1. 程式人生 > >hdu 4965 Fast Matrix Calculation(矩陣快速冪)

hdu 4965 Fast Matrix Calculation(矩陣快速冪)

觀察 while code 開始 mat col power tmp style

題意:

給你一個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(矩陣快速冪)