矩阵快速幂
by lcx,zjy
基础知识
矩阵:由个数排成的m行n列的数表
其实就是二维数组
矩阵加减法
矩阵加减法的规则:
其中 为与的和或差,即:
因此,相加减的两个矩阵的行列必须相同
矩阵乘法
矩阵乘法的规则:
其中 为A的第i行与B的第j列对应乘积的和,即:
显然两个相乘是要一行和一列对应乘,那么矩阵乘法是需要A的行数与B的列数相等的,这是A*B的前提条件
这里给个例子帮助理解:
交换即是
可见矩阵的乘法是不满足交换律的
然后就可以发现,矩阵的行数应该是的行数,列数应该是的列数,并且也是一个方阵(行数和列数相等的矩阵)
代码:
int c[N][N];
void Mul(int a[][N],int b[][N],int n){//n是矩阵大小
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
c[i][j]+=a[i][k]*b[k][j];
}
}
}
}
应用
矩阵快速幂加速递推
矩阵快速幂
矩阵幂就是算
根据矩阵乘法,可以发现矩阵乘法满足结合律:
证明:
上面两式子都等于
于是——
假设A是的矩阵,则有:
这个分段函数说明了矩阵快速幂的可行性,然后我们就可以得出算法:
把快速幂算法中的乘法改成矩阵的乘法就可以了
不过呢,还有一个问题,ans一开始的初始化是什么?
ans的初始化就相当于普通快速幂需要初始化为1,即乘上这个矩阵值不改变
可以发现:对于任意的矩阵,乘矩阵值不变,因此可以设其为初始矩阵
由此可推,ans的初始化就是对角线是1其他全是0
struct node{
int z[N][N];
};
node mul(node a,node b){//矩阵乘法
node ans;
memset(ans.z,0,sizeof(ans.z));
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
for(int k=0;k<N;k++)
ans.z[i][j]=(ans.z[i][j]+a.z[i][k]*b.z[k][j]%mod)%mod;
return ans;
}
node power(int cnt){//快速幂,只不过底数换成了矩阵
node ans,A;
memset(ans.z,0,sizeof(ans.z));
//A一些赋值
for(int i=0;i<N;i++)ans.z[i][i]=1;//ans的赋值
while(cnt){
if(cnt&1)//奇数的话ans*A
ans=mul(ans,A);
A=mul(A,A);//A平方
cnt>>=1;//幂次/2
}
return ans;
}
ps:时间复杂度
那么我们应该怎么加速递推呢?
先看一个简单的例子:
[POJ3070]Fibonacci
在Fibonacci整数序列中, = 0, =1,和 = + (n≥2).给定整数n,计算.
1.列解析式:显然:,但这个数据范围就不是很显然了。
2.建立矩阵递推式,找到转移矩阵:
分析题目可以知道:
将以上两个式子结合可得:
简写成,A矩阵就是那个2*2的常数矩阵
我们还可以把上述式子转换一下:
最后可以得到:,即:
就愉快的转换成算矩阵快速幂了
于是——
考虑情况:是的矩阵,是的矩阵,则也是的矩阵
和可以看作是一维数组,省略他们的行下标1,按照矩阵乘法的定义,有:
可以认为,通过乘上矩阵,从原始状态递推到了状态:
那么如果假设目标状态为,递推矩阵为,初始条件为,则可得出:
因为我们已经会了矩阵快速幂算法,所以唯一需要我们考虑的问题就是如何构造递推矩阵
再看几道题目:
Fibonacci前n项和
Fibonacci数列,f[1]=1,f[2]=1,f[n]=f[n-1]+f[n-2],(),输入n和m,求前n项和模m的值。(,)
设表示前项和,可推出:
因此,可得矩阵:
剩下的就和上一题一样了
[POJ3734]方块涂色
N个方块排成一列 用红,蓝,绿,黄4种颜色去涂色,求红色方块 和绿色方块个数同时为偶数的 方案数 对10007取余
1.列解析式:
先定义状态分析递推式:假设已涂完前i个方块,有:
$ a[i]b[i]c[i]$表示从1~i的方块中,红、绿方块数量都是奇数的方案数
初始:a(0)=1; b(0)=0; c(0)=0
分析a数组递推过程:
1.到i时红和绿的方格个数都是偶数,且i+1个方块被染成了蓝或黄色
2.到i时红和绿的方格个数一偶一奇,
且i+1个方块被染成了奇数个所对应的颜色
可得:
b与c的分析如上,可得:
2.建立矩阵递推式,找到转移矩阵:
由上可得:
矩阵快速幂加速递推题目特点:
1.可以抽象为长度为n的一维数组(即状态矩阵),矩阵在单位时间内变化一次
2.变化的形式是线性递推(只有若干”加法“或“乘以一个系数”的运算)
3.递推轮数大,但矩阵长度n不大
构建矩阵递推的大致套路:
上文常数矩阵就叫做转移矩阵,它能把转移到;然后这就是个等比数列,直接写出通项此处叫初始矩阵。
关键在于定义出状态矩阵和转移矩阵。
一般与都是按照原始递推式来构建的,当然可以先猜一个。
复杂度,是递归总轮数
矩阵表示修改
[THUSCH2017] 大魔法师
题目大意:n颗球,一颗球里有三个数 。有m次操作,每次操作选择一个区间进行一下七种操作之一:
1.
2.
3.
4.
5.
6.
7.输出,,
对于区间修改,我们第一想法是线段树。但是每次修改都与该点中其他属性有关,故不能整体修改
于是就想矩阵乘法来改变状态:
把一颗球看作一个的矩阵(最后一个用来维护常项)
于是我们可以很轻易的推出转移矩阵:
1.
2,3同理可得
4.
5.
6.
以第一种操作为例子,如果要修改中的数据,那就把这段区间全部都乘一个就好了,于是就可以用线段树来维护了
[BZOJ2973]石头游戏
大意:有一个行列的矩阵,还有一个与之对应的行列操作序列,一共有种操作序列,编号每一种操作序列都是长度不超过6,循环执行,一秒一个,所有格子同时进行包括:
数字0-9:拿0-9个石头到该格子
NWSE:把这个格子内所有的石头推到相邻的格子,N表示上方,W表示左方,S表示下方,E表示右方
D:拿走这个格子的石头。
问t秒之后,所有方格中石头最多的格子有多少个石头
问题分析:
以样例为例,设定一维矩阵表示秒时当前每个格子的石子数量,特别的,再加一个,使得始终为,所以,转移矩阵第列有且只有第行为
初始状态矩阵就是
第一秒的操作为,第1个格子+1,第2,3,4,5个格子推向右方,第6个格子不移动不添加
所以可以构造出转移矩阵
因此也可以通过相同的方法找到、、、...
因为和的数据范围较小,所以我们可以把行列的网络转化为长度为的一维矩阵
,其中在一维矩阵第个位置,令,也再加一个,始终为
因为每个操作序列的长度不超过,且的最小公倍数为,所以每经过秒,操作序列又会从最开始的字符开始,因此需要构造个转移矩阵,包含第行和第列
转移矩阵的构造方法:
回顾:状态矩阵所有元素与转移矩阵第列所有元素分别相乘的和,得到状态矩阵第个元素的数值
注:以下操作均不计除了当前石子外,其他石子的操作对此石子的影响
若操作数字为,设数值为,所以第列 第行 为,第列 第行 为
若为字符,则转移矩阵第行 第列为,字符类似
若为字符,则转移矩阵此列不做处理
为了保证始终为,所有转移矩阵第列有且只有第行为
所以需要将全部求解出来,令
则秒后:
状态矩阵
其中可以用矩阵快速幂求解,最后求中列的最大值即可
又可以发现一个规律:
如果在应用矩阵乘法时,遇到常数项,经常需要在“状态矩阵”中添加一个额外的位置,始终储存常数,并乘上“转移矩阵”中适当的系数,累加到“状态矩阵”的其他位置
矩阵乘法与邻接矩阵
[TJOI2017]可乐
题目:
加里敦星球的人们特别喜欢喝可乐。因而,他们的敌对星球研发出了一个可乐机器人,并且放在了加里敦星球的号城市上。这个可乐机器人有三种行为: 停在原地,去下一个相邻的城市,自爆。它每一秒都会随机触发一种行为。现在给加里敦星球城市图,在第秒时可乐机器人在号城市,问经过了秒,可乐机器人的行为方案数是多少?
表示城市个数,表示道路个数。
保证两座城市之间只有一条路相连,且没有任何一条道路连接两个相同的城市。
分析:
先用邻接矩阵存图(两个点之间若有边则)
如果我们没有在原地停留和自爆两个操作,那么就是问从起点出发,走t步的不同路径数
令该图的邻接矩阵是,那么我们考虑 是个什么东西
我们单独考虑某一行和某一列的相关运算:令其为 和 令 为相乘得到的矩阵,那么会有
容易发现,当且仅当 和 都不为零,即点可连通 两点的时候上式的该项才为, 否则为
那么所有的这些情况累加起来,就是从到长度为的路径条数(即方案数)
所以,得到的矩阵其实表示了任意两点间长度为2的方案数
(也从算法的角度考虑)那么不难发现的第行第列的数字含义是从到经过步的路径方案总数
那么在原地停留和自爆怎么处理?
在原地停留很简单,我们只要认为每个点都有一个从自己到自己的自环即可。
那自爆呢?
我们可以将自爆这个状态也看成一个城市,就设它为编号
我们在邻接矩阵上从每个点都向这个点连一条边,这个点除了自己外不连其他出边。
这样就满足了任何一个点随时可以自爆,且无法恢复到其他状态。
最后,统计答案
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】