算法竞赛进阶指南0x34矩阵乘法
矩阵的相关性质再回顾
对于一个矩阵
- 满足结合律
- 满足乘法对于加法的分配率
- 但是不满足交换律!
对于特殊一点的矩阵来说:
把最左边还有最右面的看成一个数组。。
矩阵加速大法:
因为矩阵满足结合律,所以可以使用快速幂来进行计算。
规律总结:
矩阵加速设计到两个东西:
- 状态矩阵
- 转移矩阵
- 可以抽象出一个一维向量,在每一次递推就变化一次;
- 状态转移方程不发生变化;
- 状态转移过程中,一定是线性的(加减,乘以系数)
- 注意:状态矩阵需要尽可能短,转移次数可以比较大。
时间复杂度是
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矩阵乘法的更多相关文章
- 算法竞赛进阶指南 0x00 基本算法
放在原来这个地方不太方便,影响阅读体验.为了读者能更好的刷题,另起一篇随笔. 0x00 基本算法 0x01 位运算 [题目][64位整数乘法] 知识点:快速幂思想的灵活运用 [题目][最短Hamilt ...
- 算法竞赛进阶指南--快速幂,求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 ...
- 《算法竞赛进阶指南》0x10 基本数据结构 Hash
Hash的基本知识 字符串hash算法将字符串看成p进制数字,再将结果mod q例如:abcabcdefg 将字母转换位数字(1231234567)=(1*p9+2*p8+3*p7+1*p6+2*p5 ...
- 《算法竞赛进阶指南》1.4Hash
137. 雪花雪花雪花 有N片雪花,每片雪花由六个角组成,每个角都有长度. 第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,-,ai,6. 因为雪花的形状是封闭的环形,所以从任何一 ...
- bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)算法竞赛进阶指南
题目描述 原题连接 Y岛风景美丽宜人,气候温和,物产丰富. Y岛上有N个城市(编号\(1,2,-,N\)),有\(N-1\)条城市间的道路连接着它们. 每一条道路都连接某两个城市. 幸运的是,小可可通 ...
- POJ1639 算法竞赛进阶指南 野餐规划
题目描述 原题链接 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合 ...
- 算法竞赛进阶指南0x51 线性DP
AcWing271. 杨老师的照相排列 思路 这是一个计数的题目,如果乱考虑,肯定会毫无头绪,所以我们从1号到最后一个依次进行安排. 经过反复实验,发现两个规律 每一行的同学必须是从左向右依次连续放置 ...
- 算法竞赛进阶指南0x35高斯消元与线性空间
高斯消元 目录 高斯消元 ACWing207. 球形空间产生器(点击访问) 求解思路 代码 ACWing208. 开关问题(点击访问) 思路 代码 总结 欣赏 线性空间 定义 ACWing209. 装 ...
- 算法竞赛进阶指南0x14 Hash
组成部分: 哈希函数: 链表 AcWing137. 雪花雪花雪花 因为所需要数据量过于大,所以只能以O(n)的复杂度. 所以不可能在实现的过程中一一顺时针逆时针进行比较,所以采用一种合适的数据结构. ...
随机推荐
- 基于Docker&Kubernetes构建PaaS平台基础知识梳理
点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 基于Docker&Kubernetes构建Paa ...
- 公司为什么要使用OKR,目的是什么?
原创不易,求分享.求一键三连 站在公司角度,会有一些诉求: 想知道每个人在干什么,干得怎么样: 想知道如何把更多的人卷起来: 人是不想被管束的,无论是想"度量我"还是想卷我,都是我 ...
- 在字节跳动,一个更好的企业级SparkSQL Server这么做
SparkSQL是Spark生态系统中非常重要的组件.面向企业级服务时,SparkSQL存在易用性较差的问题,导致难满足日常的业务开发需求.本文将详细解读,如何通过构建SparkSQL服务器实现使用效 ...
- js颜色调试器
1 /* ColorTestViewer 颜色调试器 2 3 attribute: 4 onchange: Function; //颜色改变回调; 默认null 5 6 //以下属性不建议直接修改 7 ...
- 最大流&最小割&费用流模版
好久都没有搞博客了.想认真写又要准备文化课期末了. ISAP 流程: 原理就是dfs找增广路. 最基础的建反向边以便反悔就不说了. 但是记录一个dep(dis)表示层数,一开始BFS(从t开始,dis ...
- Microsoft Office 代码执行漏洞临时防范方法
一.删除ms-msdt URI 注册表 1.按下键盘上的快捷组合键:win键 和 R键,打开运行(也可以在开始菜单打开运行). 2.在运行窗口中输入命令:regedit,点击确定或敲回车键就可以快速打 ...
- go-zero 微服务实战系列(一、开篇)
前言 在社区中经常看到有人问有没有基于 go-zero 的比较完整的项目参考,该类问题本质上是想知道基于 go-zero 的项目的最佳实践.完整的项目应该是一个完整的产品功能,包含产品需求.架构设计. ...
- C++ 智能指针浅析
C++ 智能指针浅析 为了解决 C++ 中内存管理这个老大难问题,C++ 11 中提供了三种可用的智能指针.(早期标准库中还存在一种 auto_ptr,但由于设计上的缺陷,已经被 unique_ptr ...
- C#实现[移除文件名中的非中文字符]
更新记录: 2022年5月28日 从程序中抽出方法复用. 处理财务文件时写的一个小函数.用于移除文件名中的非中文字符. /// <summary> /// 移除文件名中的非中文字符 /// ...
- 编程技巧│浏览器 Notification 桌面推送通知
目录 一.什么是 Notification 二.弹窗授权 三.弹窗使用 四.浏览器支持检测 五.授权回调 六.3秒后关闭弹窗 一.什么是 Notification Notification 是浏览器最 ...