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; }