zoukankan      html  css  js  c++  java
  • 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
    ", ans);
      }
      return 0;
    }


  • 相关阅读:
    Wedge 100-32X 100GbE Data Center Switch
    openstack参考资料
    进程调度
    进程管理 之 基本概念
    Linux设备驱动程序 之 中断和锁
    Linux设备驱动程序 之 工作队列
    Linux设备驱动程序 之 tasklet
    Linux设备驱动程序 之 软中断
    Linux设备驱动程序 之 中断下半部
    Linux设备驱动 之 中断处理程序
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4046836.html
Copyright © 2011-2022 走看看