http://acm.hdu.edu.cn/showproblem.php?pid=4965
给定两个矩阵A,B,分别为N*K和K*N;求出矩阵C = A*B,矩阵M=C^(N∗N)
将矩阵M中的所有元素取模6,得到新矩阵M‘,并计算矩阵M’中所有元素的和
注意到BA 得到 6*6,而AB 得到1000*1000
转化乘法算式为:M = ABABABAB.. = A(BA)^(N*N-1)B
直接用矩阵快速幂即可
#include<cstdio>
#include<cstring>
#include<algorithm>
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define clr0(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
#define N 7
int n, k;
int m;
struct Matrix{
ll mat[N][N];
void unit(){
memset(mat,0,sizeof(mat));
for (int i=0;i<k;++i) mat[i][i]=1;
}
Matrix operator*(Matrix b){
Matrix c;
memset(c.mat,0,sizeof(c.mat));
for (int i=0;i<k;++i)
for (int l=0;l<k;++l)
if (mat[i][l])
for (int j=0;j<k;++j)
{
c.mat[i][j] = (c.mat[i][j] + mat[i][l] * b.mat[l][j] % 6) % 6;
}
return c;
}
}c;
int a[1005][1005], b[1005][1005], d[1005][1005];
Matrix operator^(Matrix a,int m){
Matrix t;
t.unit();
while(m){
if (m&1) t=t*a;
a=a*a;
m>>=1;
}
return t;
}
int main(){
int i, j, l;
while (~RD2(n,k),n|k){
for (i = 0; i < n; ++i)
for (j = 0; j < k; ++j)
scanf("%d", &a[i][j]);
for (i = 0; i < k; ++i)
for (j = 0; j < n; ++j)
scanf("%d", &b[i][j]);
clr0(c.mat);
for (i = 0; i < k; ++i)
for (l = 0; l < n; ++l)
for (j = 0; j < k; ++j)
c.mat[i][j] += (b[i][l] * a[l][j]);
m = n * n - 1;
c = c ^ m;
clr0(d);
for (i = 0; i < n; ++i)
for (l = 0; l < k; ++l)
for (j = 0; j < k; ++j)
d[i][j] = (d[i][j] + a[i][l] * c.mat[l][j]) % 6;
clr0(a);
for (i = 0; i < n; ++i)
for (l = 0; l < k; ++l)
for (j = 0; j < n; ++j)
a[i][j] = (a[i][j] + d[i][l] * b[l][j]) % 6;
ll ans = 0;
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
ans += a[i][j];
printf("%I64d\n", ans);
}
return 0;
}
浙公网安备 33010602011771号