题意:

     给两个矩阵,n*m的矩阵A,和m*n的矩阵B,

求(A*B)^(n*n)其中 m<=6,n<=1000。

思路:

      一开始直接模拟,写了个矩阵快速幂,超时了,因为A*B后得到的是1000*1000的矩阵,做乘法直接超时了,后来写了个这样的

    (A*B)^(n*n) = (A*B)*(A*B)*(A*B)...

                       = A * (B*A)*(B*A)*(B*A)...*B

矩阵虽然没有交换律但是有结合律,我们直接先B*A(得到的是一个最大6*6的矩阵)然后快速幂,然后再A * BA^(n*n-1) * B这样就行了,然后又超时了,算了很多次,感觉不可能超时,但还是超时了,原因就是我所有的矩阵用的都是mat[1002][1002]为了方便我都开结构体了,结果各种超时,最后没办法了,全都开数组,然后去模拟,A[1002][8],B[8][1002],BA[8][8]...,这样就AC了,难道开大的数组也会浪费很多时间?(这个地方头一次碰到)。


#include<stdio.h>
#include<string.h>

typedef struct
{
int
mat[8][8];
}
AA; int A[1002][8] ,B[8][1002] ,C[1002][1002];
int
nmm[1002][8]; AA mat_matba(int n ,int m)
{

AA c;
memset(c.mat ,0 ,sizeof(c.mat));
for(int
k = 1 ;k <= n ;k ++)
for(int
i = 1 ;i <= m ;i ++)
if(
B[i][k])
for(int
j = 1 ;j <= m ;j ++)
c.mat[i][j] = (c.mat[i][j] + B[i][k] * A[k][j])%6 ;
return
c;
}
AA mat_mat(AA a ,AA b ,int n)
{

AA c;
memset(c.mat ,0 ,sizeof(c.mat));
for(int
k = 1 ;k <= n ;k ++)
for(int
i = 1 ;i <= n ;i ++)
if(
a.mat[i][k])
for(int
j = 1 ;j <= n ;j ++)
c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % 6;
return
c;
}
AA quick_mat(AA a ,int b ,int n)
{

AA c;
memset(c.mat ,0 ,sizeof(c.mat));
for(int
i = 1 ;i <= n ;i ++)
c.mat[i][i] = 1;
while(
b)
{
if(
b&1) c = mat_mat(c ,a ,n);
a = mat_mat(a ,a ,n);
b >>= 1;
}
return
c;
} void
mat_matnmm(AA mm ,int n ,int m)
{

memset(nmm ,0 ,sizeof(nmm));
for(int
k = 1 ;k <= m ;k ++)
for(int
i = 1 ;i <= n ;i ++)
if(
A[i][k])
for(int
j = 1 ;j <= m ;j ++)
nmm[i][j] = (nmm[i][j] + A[i][k] * mm.mat[k][j]) % 6;
} void
mat_matnmmn(int n ,int m)
{

memset(C ,0 ,sizeof(C));
for(int
k = 1 ;k <= m ;k ++)
for(int
i = 1 ;i <= n ;i ++)
for(int
j = 1 ;j <= n ;j ++)
C[i][j] = (C[i][j] + nmm[i][k] * B[k][j]) % 6;
} int main ()
{
int
n ,m ,i ,j;
while(~
scanf("%d %d" ,&n ,&m) && n + m)
{
for(
i = 1 ;i <= n ;i ++)
for(
j = 1 ;j <= m ;j ++)
scanf("%d" ,&A[i][j]);
for(
i = 1 ;i <= m ;i ++)
for(
j = 1 ;j <= n ;j ++)
scanf("%d" ,&B[i][j]);
AA c = mat_matba(n ,m);
AA ban = quick_mat(c ,n*n-1 ,m);
mat_matnmm(ban ,n ,m);
mat_matnmmn(n ,m); int sum = 0;
for(
i = 1 ;i <= n ;i ++)
for(
j = 1 ;j <= n ;j ++)
sum += C[i][j];
printf("%d\n" ,sum);
}
return
0;
}

hdu4965 巧用矩阵乘法结合律的更多相关文章

  1. Luogu P4643 【模板】动态dp

    题目链接 Luogu P4643 题解 猫锟在WC2018讲的黑科技--动态DP,就是一个画风正常的DP问题再加上一个动态修改操作,就像这道题一样.(这道题也是PPT中的例题) 动态DP的一个套路是把 ...

  2. LG4719 【模板】动态dp 及 LG4751 动态dp【加强版】

    题意 题目描述 给定一棵\(n\)个点的树,点带点权. 有\(m\)次操作,每次操作给定\(x,y\),表示修改点\(x\)的权值为\(y\). 你需要在每次操作之后求出这棵树的最大权独立集的权值大小 ...

  3. DirectX12 3D 游戏开发与实战第二章内容

    矩阵代数 学习目标 理解矩阵及其相关运算的定义 探究为何能把向量和矩阵的乘法视为一种线性组合 学习单位矩阵.转置矩阵.行列式以及矩阵的逆等概念 逐步熟悉DirectXMath库中提供的关于矩阵计算的类 ...

  4. DP大大大大大赏

    还是前置: 动态规划的三种实现方法: 递推,递归,记忆化搜索 然后还是从斐波那契数列开始引入: 两种求斐波那契数列的方法: 1.用其他位置的结果得到自己的结果: 2.用自己的结果算其他的结果: 以上两 ...

  5. CS229 斯坦福大学机器学习复习材料(数学基础) - 线性代数

    CS229 斯坦福大学机器学习复习材料(数学基础) - 线性代数 线性代数回顾与参考 1 基本概念和符号 1.1 基本符号 2 矩阵乘法 2.1 向量-向量乘法 2.2 矩阵-向量乘法 2.3 矩阵- ...

  6. CS229 机器学习课程复习材料-线性代数

    本文是斯坦福大学CS 229机器学习课程的基础材料,原始文件下载 原文作者:Zico Kolter,修改:Chuong Do, Tengyu Ma 翻译:黄海广 备注:请关注github的更新,线性代 ...

  7. HDU4965 Fast Matrix Calculation —— 矩阵乘法、快速幂

    题目链接:https://vjudge.net/problem/HDU-4965 Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Othe ...

  8. hdu4965 Fast Matrix Calculation (矩阵快速幂 结合律

    http://acm.hdu.edu.cn/showproblem.php?pid=4965 2014 Multi-University Training Contest 9 1006 Fast Ma ...

  9. hdu4965 Fast Matrix Calculation 矩阵快速幂

    One day, Alice and Bob felt bored again, Bob knows Alice is a girl who loves math and is just learni ...

随机推荐

  1. OpenGL中的坐标系统详细概括:包括Z缓冲

    一: 首先就是关于几个坐标系统的概括: 局部坐标是对象相对于局部原点的坐标,也是物体起始的坐标. 下一步是将局部坐标变换为世界空间坐标,世界空间坐标是处于一个更大的空间范围的.这些坐标相对于世界的全局 ...

  2. C#连接Excel读取与写入数据库SQL ( 上 )

    第一次写C#与sql的东西,主要任务是从Excel读取数据,再存到SQL server中. 先上读取Excel文件的code如下. public bool GetFiles(string equipN ...

  3. Hi3559AV100 NNIE RFCN开发:V4L2->VDEC->VPSS->NNIE->VGS->VO系统整体动态调试实现

    下面随笔将给出Hi3559AV100 NNIE RFCN开发:V4L2->VDEC->VPSS->NNIE->VGS->VO系统整体动态调试实现,最终的效果是:USB摄像 ...

  4. 不一样的软件们——GitHub 热点速览 v.21.10

    作者:HelloGitHub-小鱼干 创意,是程序员的一个身份代名词,一样的软件有不一样的玩法.比如,你可以像用 git 一样操作一个 SQL 数据库,dolt 就是这样的数据库.又比如,你可以只写文 ...

  5. 200-Java语言基础-Java编程入门-004 | Java分支与循环

    一.流程控制语句 可以控制程序的执行流程 在程序开发的过程之中一共会存在有三种程序逻辑:顺序结构.条件分支(选择)结构.循环结构. 顺序结构的定义,即:所有的程序将按照定义的代码从上往下.顺序依次执行 ...

  6. js输入框只能输入数字

    1.只允许输入数字 <input type="text"  onkeyup="this.value=this.value.replace(/\D/g,'')&quo ...

  7. IDApro 快捷键

    https://www.hex-rays.com/wp-content/static/products/ida/idapro_cheatsheet.html File Operations Parse ...

  8. 攻防世界 reverse hackme

    hackme XCTF 3rd-GCTF-2017 __int64 __fastcall sub_400F8E(__int64 a1, __int64 a2) { char input[136]; / ...

  9. Qt添加注释模板

    背景 软件:Qt Creator 在写代码的时候我们为了规范化,一般会加文件注释.类注释和函数注释 用注释来说明我们的代码,也方便模块化开发 那么我们在写注释的时候经常会写一些重复的内容,我们会复制粘 ...

  10. python基础之流程控制(1)

    一.分支结构:if 判断 1.什么要有if 判断语句? 让计算机可以像人一样根据条件进行判断,并根据判断结果执行相应的流程. 2.基本结构 单分支结构 # 单分支 if 条件1: 代码1 代码2 代码 ...