hdu 4965 矩阵快速幂

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


你可能感兴趣的:(HDU)