Fast Matrix Calculation HDU - 4965(矩阵+式子转换)
题意:给一个A矩阵大小为n*K,B矩阵大小为K*n。求(A*B)^(n*n)的矩阵的所有元素和。n<=1000,K<=6。
思路:首先结构体中最大开800*800,如果直接算就无法运行。所以要想到式子转化为A*(B*A)^(n*n-1)*B。这样只要最多开6*6了
剩下的就都是手写矩阵乘法了。
#include <bits/stdc++.h> using namespace std; #define ll long long const int N=10; const int mod=6; struct Matrix { int n, m, g[N][N]; Matrix(){} Matrix(int _n, int _m) { n = _n; m = _m; for(int i=0;i<=n;i++) { for(int j=0;j<=m;j++) { g[i][j]=0; } } } // 矩阵相乘 Matrix operator * (const Matrix& y) { Matrix z(n, y.m); for(int i=0; i<n; i++) for(int j=0; j<y.m; j++) for(int k=0; k<m; k++){ int tmp=(long long )g[i][k]*y.g[k][j]%mod; z.g[i][j]=(z.g[i][j]+tmp)%mod; } return z; } }; // 矩阵模幂 Matrix Matrix_Powmul(Matrix x, int m) { Matrix z(x.n, x.n); for(int i=0; i<x.n; i++) z.g[i][i] = 1; while(m) { if(m & 1) z = z * x; x = x * x; m >>= 1; } return z; } int t1[1010][10]; int t2[10][1010]; int ans[1010][1010]; int ans1[1010][1010]; int main() { int n,K; //printf("111\n"); while(~scanf("%d%d",&n,&K)) { if(n==0&&K==0) { break; } for(int i=0;i<=max(n,K);i++) { for(int j=0;j<=max(n,K);j++) { ans[i][j]=0; ans1[i][j]=0; } } for(int i=0;i<n;i++) { for(int j=0;j<K;j++) { scanf("%d",&(t1[i][j])); } } for(int i=0;i<K;i++) { for(int j=0;j<n;j++) { scanf("%d",&(t2[i][j])); } } if(n==1) { for(int i=0; i<n; i++) for(int j=0; j<n; j++) for(int k=0; k<K; k++){ int tmp=(long long )t1[i][k]*t2[k][j]%mod; ans[i][j]=(ans[i][j]+tmp)%mod; } } else { Matrix tt=Matrix(K,K); for(int i=0; i<K; i++) for(int j=0; j<K; j++) for(int k=0; k<n; k++){ int tmp=(long long )t2[i][k]*t1[k][j]%mod; tt.g[i][j]=(tt.g[i][j]+tmp)%mod; } tt=Matrix_Powmul(tt,n*n-1); for(int i=0; i<n; i++) for(int j=0; j<K; j++) for(int k=0; k<K; k++){ int tmp=(long long )t1[i][k]*tt.g[k][j]%mod; ans1[i][j]=(ans1[i][j]+tmp)%mod; } for(int i=0; i<n; i++) for(int j=0; j<n; j++) for(int k=0; k<K; k++){ int tmp=(long long )ans1[i][k]*t2[k][j]%mod; ans[i][j]=(ans[i][j]+tmp)%mod; } } int sum=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { sum=(sum+ans[i][j]); } } printf("%d\n",sum); } }