题目链接:点击打开链接
题意:一个N*K的矩阵A和一个K*N的矩阵B(0<N<=1000,0<K<=10),求矩阵(A*B)^(N*N)中所有元素的和;
思路:我们可以利用矩阵乘法的性质把(A*B)^(N*N)转化为A*(B*A)^(N*N-1)*B.
/**********************************************************************
Problem : 4965 ( Fast Matrix Calculation ) Judge Status : Accepted
RunId : 11498662 Language : C++ Author : alpc_wcq
Code Render Status : Rendered By HDOJ C++ Code Render Version 0.01 Beta
**********************************************************************/
#include <cmath>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 6
struct Matrix{
int m;
int data[maxn][maxn];
Matrix(int me):m(me){
memset(data,0,sizeof(data));}
Matrix operator * (const Matrix& a){
Matrix ret(m);
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
for(int k=0;k<m;k++)
{
ret.data[i][j]+=data[i][k]*a.data[k][j];
}
ret.data[i][j]=(ret.data[i][j]%6);
}
}
return ret;
}
void sete()
{
for(int i=0;i<m;i++)
{
data[i][i]=1;
}
}
};
Matrix powmod(Matrix a,int n)
{
Matrix ret(a.m);
ret.sete();
Matrix T=a;
for(int i=n;i;i>>=1,T=T*T)
{
if(i%2)
{
ret=ret*T;
}
}
return ret;
}
void read(int &a) {
int t;
while (t = getchar(), isspace(t));
a = t - '0';
while (t = getchar(), !isspace(t)) a = a * 10 + t - '0';
}
int main ()
{
//freopen("data.in","r",stdin);
int n,k,i,j,ke;
int date[1000][maxn],date2[maxn][1000],date1[1000][maxn];
while (1)
{
// scanf("%d%d",&n,&k);
read(n);read(k);
if(n==0,k==0) break;
for(i=0;i<n;i++)
{
for(j=0;j<k;j++)
{
read(date[i][j]);
}
}
for(i=0;i<k;i++)
{
for(j=0;j<n;j++)
{
read(date2[i][j]);
}
}
Matrix tp(k);
for(i=0;i<k;i++)
{
for(j=0;j<k;j++)
{
for(ke=0;ke<n;ke++)
{
tp.data[i][j]+=date[ke][j]*date2[i][ke];
}
tp.data[i][j]=tp.data[i][j]%6;
}
}
tp=powmod(tp,n*n-1);
for(i=0;i<n;i++)
{
for(j=0;j<k;j++)
{
date1[i][j]=0;
for(ke=0;ke<k;ke++)
{
date1[i][j]+=date[i][ke]*tp.data[ke][j];
}
date1[i][j]=date1[i][j]%6;
// printf("date[%d] [%d] :%2d ",i,j,date1[i][j]);
}
//puts("");
}
int anse=0,temp;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
temp=0;
for(ke=0;ke<k;ke++)
{
temp+=(date1[i][ke]*date2[ke][j]);
}
anse+=(temp%6);
//printf("temp %2d %d ",temp,temp%6);
}
// puts("");
}
printf("%d\n",anse);
}
return 0;
}