矩阵的相关性质再回顾

对于一个矩阵

  1. 满足结合律
  2. 满足乘法对于加法的分配率
  3. 但是不满足交换律!

对于特殊一点的矩阵来说:

把最左边还有最右面的看成一个数组。。

矩阵加速大法:

因为矩阵满足结合律,所以可以使用快速幂来进行计算。
规律总结:
矩阵加速设计到两个东西:

  • 状态矩阵
  • 转移矩阵
  1. 可以抽象出一个一维向量,在每一次递推就变化一次;
  2. 状态转移方程不发生变化;
  3. 状态转移过程中,一定是线性的(加减,乘以系数)
  4. 注意:状态矩阵需要尽可能短,转移次数可以比较大。

时间复杂度是

N

3

l

o

g

N

N^3logN

N3logN.

ACWing205. 斐波那契



要注意取模

代码

#include <bits/stdc++.h>
using namespace std;
const int len = 2;
const int mod = 10000;
void mulself(int a[2][2])
{
int c[2][2];
memset(c, 0, sizeof(c));
for(int i = 0; i < len; i++ )
for(int j = 0; j < len; j++)
for(int k = 0; k < len; k++)
c[i][j] = (c[i][j]+(long long)a[i][k] * a[k][j])%mod;
memcpy(a, c, sizeof(c));
}
void mul(int a[2][2], int f[2])
{
int c[2];
memset(c, 0, sizeof(c));
for(int j = 0; j < len; j++)
for(int k = 0; k < len; k++)
c[j] = (c[j] + (long long)f[k] * a[k][j])%mod;
memcpy(f, c, sizeof(c));
}
void solve(int n)
{
int a[2][2] = {{0, 1}, {1, 1}};
int f[2] = {0, 1};
for(; n; n >>= 1 )
{
if(n&1) mul(a, f);
mulself(a);
}
printf("%d\n", f[0]);
}
int main()
{
int n;
while((scanf("%d", &n)||1) && n != -1) solve(n);
return 0;
}

ACWing206. 石头游戏


解题思路:

感受:

太恶心了,一百多行代码,debug了一下午

代码


//在这个程序中所有的数组全部从1开始计数
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,t,act;
char op[20][20];//表示操作
ll oplen[20];
ll mp[70];//表示单元格映射的操作数字
ll matrix[70][70][70];
ll p;//p表示状态矩阵的从 0 到 p;
inline ll num(ll x, ll y)
{
if(x==0 && y==0) return 0;
return (x-1)*m + y;
}
void read_op_and_mp()
{
char buf[12];
for(int i = 1; i <= n; i++)
{
scanf("%s", buf+1);
for(int j = 1; j <= m; j++)
{
mp[num(i, j)] = buf[j]-'0'+1;
}
}
for(int i = 1; i <= act; i++)
{
scanf("%s", op[i]+1);
oplen[i] = strlen(op[i]+1);
}
}
void mulself(ll a[70][70])//
{
ll c[70][70];
memset(c, 0, sizeof(c));
for(int i = 0; i<= p; i++)
for(int j = 0; j <= p; j++)
for(int k = 0; k <= p; k++)
c[i][j] += a[i][k] * a[k][j];
memcpy(a, c, sizeof(c));
}
void mul(ll f[], ll a[70][70])
{
ll c[70];
memset(c, 0, sizeof(c));
for(int j = 0; j <= p; j++)
for(int k = 0; k <= p; k++)
{
c[j] += f[k] * a[k][j];
}
memcpy(f, c, sizeof(c));//sizeof不能是f因为f是指针。
}
void make_matrix()
{
ll tmp[70][70];
for(int i = 0; i <= p; i++) matrix[0][i][i] = 1;//设置为单位矩阵
for(int tt = 1; tt <= 60; tt++)
{
memset(tmp, 0, sizeof(tmp));
tmp[0][0] = 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
char ch = op[mp[num(i, j)]][(tt-1)%oplen[mp[num(i, j)]]+1];
if('0' <= ch && ch <= '9')
{
tmp[num(0, 0)][num(i, j)] = ch-'0';
tmp[num(i, j)][num(i, j)] = 1;
}
else if(ch=='N')
{
if(i > 1) tmp[num(i, j)][num(i-1, j)] = 1;
}
else if(ch=='W')
{
if(j > 1) tmp[num(i, j)][num(i, j-1)] = 1;
}
else if(ch=='S')
{
if(i < n) tmp[num(i, j)][num(i+1, j)] = 1;
}
else if(ch=='E')
{
if(j < m) tmp[num(i, j)][num(i, j+1)] = 1;
}
}
for(int i = 0; i <= p; i++)
for(int j = 0; j <= p; j++)
for(int k = 0; k <= p; k++)
{
matrix[tt][i][j] += matrix[tt-1][i][k] * tmp[k][j];
}
}
}
ll solve()
{
ll ret = 0;
ll f[70] = {0};
f[0] = 1;
ll a[70][70];
make_matrix();
memcpy(a, matrix[60], sizeof(a));
ll xx = t / 60;
for(; xx; xx >>= 1)
{
if(xx&1) mul(f, a);
mulself(a);
}
mul(f, matrix[t%60]);
for(int i = 1; i <= p; i++) ret = max(ret, f[i]);
return ret;
}
int main()
{
cin >> n >> m >> t >> act;
read_op_and_mp();
p = m * n;
ll ans = solve();
cout << ans << endl;
return 0;
}

算法竞赛进阶指南0x34矩阵乘法的更多相关文章

  1. 算法竞赛进阶指南 0x00 基本算法

    放在原来这个地方不太方便,影响阅读体验.为了读者能更好的刷题,另起一篇随笔. 0x00 基本算法 0x01 位运算 [题目][64位整数乘法] 知识点:快速幂思想的灵活运用 [题目][最短Hamilt ...

  2. 算法竞赛进阶指南--快速幂,求a^b mod p

    // 快速幂,求a^b mod p int power(int a, int b, int p) { int ans = 1; for (; b; b >>= 1) { if (b &am ...

  3. 《算法竞赛进阶指南》0x10 基本数据结构 Hash

    Hash的基本知识 字符串hash算法将字符串看成p进制数字,再将结果mod q例如:abcabcdefg 将字母转换位数字(1231234567)=(1*p9+2*p8+3*p7+1*p6+2*p5 ...

  4. 《算法竞赛进阶指南》1.4Hash

    137. 雪花雪花雪花 有N片雪花,每片雪花由六个角组成,每个角都有长度. 第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,-,ai,6. 因为雪花的形状是封闭的环形,所以从任何一 ...

  5. bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)算法竞赛进阶指南

    题目描述 原题连接 Y岛风景美丽宜人,气候温和,物产丰富. Y岛上有N个城市(编号\(1,2,-,N\)),有\(N-1\)条城市间的道路连接着它们. 每一条道路都连接某两个城市. 幸运的是,小可可通 ...

  6. POJ1639 算法竞赛进阶指南 野餐规划

    题目描述 原题链接 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合 ...

  7. 算法竞赛进阶指南0x51 线性DP

    AcWing271. 杨老师的照相排列 思路 这是一个计数的题目,如果乱考虑,肯定会毫无头绪,所以我们从1号到最后一个依次进行安排. 经过反复实验,发现两个规律 每一行的同学必须是从左向右依次连续放置 ...

  8. 算法竞赛进阶指南0x35高斯消元与线性空间

    高斯消元 目录 高斯消元 ACWing207. 球形空间产生器(点击访问) 求解思路 代码 ACWing208. 开关问题(点击访问) 思路 代码 总结 欣赏 线性空间 定义 ACWing209. 装 ...

  9. 算法竞赛进阶指南0x14 Hash

    组成部分: 哈希函数: 链表 AcWing137. 雪花雪花雪花 因为所需要数据量过于大,所以只能以O(n)的复杂度. 所以不可能在实现的过程中一一顺时针逆时针进行比较,所以采用一种合适的数据结构. ...

随机推荐

  1. 离谱的 CSS!从表盘刻度到艺术剪纸

    某日,群里有这样一个问题,如何实现这样的表盘刻度: 这其实是个挺有意思的问题,方法也有很多. 单标签,使用 conic-gradient 实现表盘刻度 最简单便捷的方式,就是利用角向渐变的方式 con ...

  2. xrdp出现xrdp vnc error problem connecting解决办法

    # generate a file called .xsession in your home directory, and set default desktop echo "xfce4- ...

  3. wait 和async,await一起使用引发的死锁问题

    在某个项目开发过程中,偶然间发现在UI线程中async,await,wait三者一起使用会引发一个必然性的死锁问题. 一个简单的实例,代码很简单,在界面上放置一个Button,并在Button的cli ...

  4. windows 10 21H1 顶部任务栏点击音量或其他图标不出弹框

    右键任务栏,按照图片中描述操作

  5. 905. Sort Array By Parity - LeetCode

    Question 905. Sort Array By Parity Solution 题目大意:数组排序,偶数放前,奇数在后,偶数的数之间不用管顺序,奇数的数之间也不用管顺序 思路:建两个list, ...

  6. 记 iTextSharp 剪裁 PDF 指定区域的方法

    原文 引用 itextsharp 5.5.13.2 itextsharp.xtra 5.5.13.2 方法 /// <summary> /// 截取pdf文件,例如把A4截出指定的A6区域 ...

  7. python并发编程之线程/协程

    python并发编程之线程/协程 part 4: 异步阻塞例子与生产者消费者模型 同步阻塞 调用函数必须等待结果\cpu没工作input sleep recv accept connect get 同 ...

  8. 0-1knapsack

    Python 实现0-1背包问题(回溯法) 题目 解题思路 回溯法:为了避免生成那些不可能产生最佳解的问题状态,要不断地利用限界函数(bounding function)来处死那些实际上不可能产生所需 ...

  9. [react] 什么是虚拟dom?虚拟dom比操作原生dom要快吗?虚拟dom是如何转变成真实dom并渲染到页面的?

    壹 ❀ 引 虚拟DOM(Virtual DOM)在前端领域也算是老生常谈的话题了,若你了解过vue或者react一定避不开这个话题,因此虚拟DOM也算是面试中常问的一个点,那么通过本文,你将了解到如下 ...

  10. JuiceFS V1.0 RC1 发布,大幅优化 dump/load 命令性能, 深度用户不容错过

    各位社区的伙伴, JuiceFS v1.0 RC1 今天正式发布了!这个版本中,最值得关注的是对元数据迁移备份工具 dump/load 的优化. 这个优化需求来自于某个社区重度用户,这个用户在将亿级数 ...