补一补之前的坑

因为上次关于矩阵的那篇blog写的内容太多太宽泛了,所以这次把一些板子和基本思路理一理

先看这道模板题:P3390 【模板】矩阵快速幂

首先我们知道矩阵乘法满足结合律而不满足交换律的一种运算

因此我们对于矩阵A的p次只需要先算出A^(p/2)即可

这不就是快速幂吗,快速幂的模板看这里

然后我们把其中的整数乘法改成矩阵乘法即可

关于矩阵的其他东西都不会,好吧,看一看概述矩阵

CODE

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=105,mod=1e9+7;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(LL &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void write(int x)
{
if (x/10) write(x/10);
putchar(x%10+'0');
}
struct Matrix
{
int n,m;
LL a[N][N];
inline void input(void)
{
for (register int i=1;i<=n;++i)
for (register int j=1;j<=m;++j)
read(a[i][j]);
}
inline void output(void)
{
for (register int i=1;i<=n;++i,putchar('\n'))
for (register int j=1;j<=m;++j)
write(a[i][j]),putchar(' ');
}
inline void cri_init(void)
{
memset(a,0,sizeof(a));
for (register int i=1;i<=n;++i)
a[i][i]=1;
}
};
LL k,n;
inline Matrix mul(Matrix A,Matrix B)
{
Matrix C; C.n=A.n; C.m=B.m;
memset(C.a,0,sizeof(C.a));
for (register int i=1;i<=C.n;++i)
for (register int j=1;j<=C.m;++j)
for (register int k=1;k<=A.m;++k)
C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%mod;
return C;
}
inline Matrix quick_pow(Matrix A,LL p)
{
Matrix T; T.n=T.m=n; T.cri_init();
while (p)
{
if (p&1) T=mul(T,A);
A=mul(A,A); p>>=1;
}
return T;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
read(n); read(k);
Matrix A; A.n=A.m=n;
A.input();
A=quick_pow(A,k);
A.output();
return 0;
}

再看这道题:P1939 【模板】矩阵加速(数列)

主要讲一下矩阵与递推之间如何转化

首先我们看题目给出的式子:

  • a[1]=a[2]=a[3]=1

  • a[x]=a[x-3]+a[x-1] (x>3)

首先我们通过题目给出的初始值得到初始的列向量

1 a[1]

1 分别表示 a[2]

1 a[3]

我们发现,当前的这一项与它的前三项都有关,因此我们可以建立一个3*3的矩阵

然后因为a[4]=a[1]+a[3],而稍加推导可以将a[2]代替a[1]的位置,a[3]代替a[2]的位置

注意这里就很重要了,因为a[1]对于a[5]以及以后的推导没有任何作用了,因此可以直接被覆盖

可以结合滚动数组的思想进行一下理解

然后我们得出递推矩阵:

0 1 0

0 0 1

1 0 1

手推一下就会发现刚好完成了想要的效果

然后我们只需要把初始的列向量乘递推矩阵(n-3)次即可

矩阵快速幂求之

CODE

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=4,mod=1e9+7;
struct Matrix
{
int n,m;
LL a[N][N];
inline void Dt_init(void)
{
n=m=3; memset(a,0,sizeof(a));
a[1][2]=a[2][3]=a[3][1]=a[3][3]=1;
}
inline void cri_init(void)
{
n=m=3; memset(a,0,sizeof(a));
for (register int i=1;i<=n;++i)
a[i][i]=1;
}
};
int t,n;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void write(int x)
{
if (x/10) write(x/10);
putchar(x%10+'0');
}
inline Matrix mul(Matrix A,Matrix B)
{
Matrix C; C.n=A.n; C.m=B.m;
memset(C.a,0,sizeof(C.a));
for (register int i=1;i<=C.n;++i)
for (register int j=1;j<=C.m;++j)
for (register int k=1;k<=A.m;++k)
C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%mod;
return C;
}
inline Matrix quick_pow(Matrix A,int p)
{
Matrix T; T.cri_init();
while (p)
{
if (p&1) T=mul(T,A);
A=mul(A,A); p>>=1;
}
return T;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
read(t);
while (t--)
{
read(n); Matrix F; F.Dt_init();
if (n<=3) { puts("1"); continue; }
F=quick_pow(F,n-3);
write((F.a[3][1]+F.a[3][2]+F.a[3][3])%mod); putchar('\n');
}
return 0;
}

最后我们简单总结一下用矩阵乘法优化递推的步骤:

  1. 通过题目给出的关系得出线性递推关系

  2. 列出初始矩阵的值,通常根据初始条件确定

  3. 通过递推式,得到每一项的关系由那些地方转移过来,一般来说,就可以吧推得的当前项的项在矩阵中的位置附上1(如果有乘的关系就赋成负数),但具体还是根据题目意思而定

  4. 通过矩阵快速幂来优化乘法,得到最终矩阵并与初始矩阵相乘

然后就静候AC吧

Luogu P3390 【模板】矩阵快速幂&&P1939 【模板】矩阵加速(数列)的更多相关文章

  1. 51nod 1113 矩阵快速幂( 矩阵快速幂经典模板 )

    1113 矩阵快速幂 链接:传送门 思路:经典矩阵快速幂,模板题,经典矩阵快速幂模板. /******************************************************* ...

  2. poj 3070 Fibonacci (矩阵快速幂乘/模板)

    题意:给你一个n,输出Fibonacci (n)%10000的结果 思路:裸矩阵快速幂乘,直接套模板 代码: #include <cstdio> #include <cstring& ...

  3. HDU6395-Sequence 矩阵快速幂+除法分块 矩阵快速幂模板

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门  原题目描述在最下面. Solution ...

  4. 51nod 矩阵快速幂(模板题)

    1113 矩阵快速幂  基准时间限制:3 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 给出一个N * N的矩阵,其中的元素均为正整数.求这个矩阵的M次方.由于M次方的计算结果太大 ...

  5. Fibonacci----poj3070(矩阵快速幂, 模板)

    题目链接:http://poj.org/problem?id=3070 . 就是斐波那契的另一种表示方法是矩阵的幂: 所以是矩阵快速幂:矩阵快速幂学习 #include <cstdio> ...

  6. HDU1757-A Simple Math Problem,矩阵快速幂,构造矩阵水过

    A Simple Math Problem 一个矩阵快速幂水题,关键在于如何构造矩阵.做过一些很裸的矩阵快速幂,比如斐波那契的变形,这个题就类似那种构造.比赛的时候手残把矩阵相乘的一个j写成了i,调试 ...

  7. HDU 2276 Kiki & Little Kiki 2( 矩阵快速幂 + 循环同构矩阵 )

    蒟蒻的我还需深入学习 链接:传送门 题意:给出一个长度为 n,n 不超过100的 01 串 s ,每当一个数字左侧为 1 时( 0的左侧是 n-1 ),这个数字就会发生改变,整个串改变一次需要 1s ...

  8. HDU_4965 Fast Matrix Calculation 2014多校9 矩阵快速幂+机智的矩阵结合律

    一开始看这个题目以为是个裸的矩阵快速幂的题目, 后来发现会超时,超就超在  M = C^(N*N). 这个操作,而C本身是个N*N的矩阵,N最大为1000. 但是这里有个巧妙的地方就是 C的来源其实 ...

  9. 【luogu P3390 矩阵快速幂】 模板

    题目链接:https://www.luogu.org/problemnew/show/P3390 首先要明白矩阵乘法是什么 对于矩阵A m*p  与  B p*n 的矩阵 得到C m*n 的矩阵 矩阵 ...

随机推荐

  1. 《Inside C#》笔记(完) 程序集

    程序集内部包含了各种相关的模块.资源文件.配置文件等,将这些在功能上相关的文件整合到单个文件中,以便于部署和维护.使用C#编译器编译程序时,生成的便是程序集. 一.清单数据 a)如果编译的是独立应用程 ...

  2. (网页)Java程序员们最常犯的10个错误(转)

    转自CSDN: 1.将数组转化为列表 将数组转化为一个列表时,程序员们经常这样做: List<String> list = Arrays.asList(arr); Arrays.asLis ...

  3. (网页)HTML小技巧的一些小技巧

    转自CSDN: 1.怎样定义网页语言(字符集)?            在制作网页过程中,你首先要定义网页语言,以便访问者浏览器自动设置语言,而我们用所见即所得的HTML工具时,都没有注意到这个问题, ...

  4. 使用windows命令和iconv.exe批量转换文件编码

    iconv是知名的开源跨平台编码转换库,iconv.exe是iconv库在windows下的命令行工具,iconv.exe的一般用法:iconv.exe -f gbk -t utf-8 gbk.txt ...

  5. Redis系列(一):Redis的简介与安装

    原文链接(转载请注明出处):Redis系列(一):Redis的简介与安装 什么是 Redis Redis 是一个使用ANSI C 编写的开源.支持网络协议.基于内存.可选持久性的键值对数据库,它是一个 ...

  6. python第七十七天---HTML

    HTML5 :规则, 浏览器的通用规则 1.规则, 浏览器的通用规则 2.开发者: 学习html 规则 开发后台程序 - 写html文件 (当作模板) - 数据库获取数据,替换到指定的HTML文件中的 ...

  7. C# Aspose.Cells方式导入Excel文件

    读取Excel 类 我返回的是DataTable 类型 也可以返回DataSet类型 public class XlsFileHelper { public DataTable ImportExcel ...

  8. WFE和WFI的区别

    1. 概念: WFI(Wait for interrupt)和WFE(Wait for event)是两个让ARM核进入low-power standby模式的指令,由ARM architecture ...

  9. Centos7系统如何不重启系统识别新添加的硬盘?

    今天在系统开机后插入三块硬盘,结果没有一块硬盘被系统识别到.后来找到了方法. echo "- - -" > /sys/class/scsi_host/host0/scan 上 ...

  10. linux运行apache出现403错误

    1.文档权限问题,这是linux操作系统下经常会遇到的问题,需要使用chmod的指令把网站所在目录的权限提升到755.2.SElinux,开启它也会导致403错误的产生. 查看SELinux状态:1. ...