博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【总结】 矩阵快速幂
阅读量:4994 次
发布时间:2019-06-12

本文共 1787 字,大约阅读时间需要 5 分钟。

前言

如果有不清楚矩阵乘法的,可以加QQ了解一下:3099895260

如果会的话可以跳过这个步骤

就是我们设两个矩阵为\(a\),\(b\)。他们两个可以乘在一起当且仅当第一个矩阵为\(n*p\)且第二个矩阵\(p*m\),他们乘起来的结果是\(c\)矩阵,\(n*m\)

然后乘法就是这样子实现的.

for(int i=1;i<=n;i++)    for(int j=1;j<=m;j++)        for(int k=1;k<=p;k++)            c[i][j]=a[i][k]*b[k][j];

然后如果有多个同样子的矩阵乘在一起,就可以像普通乘法快速幂。

正话

矩阵快速幂的板子基本上是没有用的,真正在题目中出现的还是矩阵加速。

我们先来看一道题目:

这显然是递推对吧,但是因为\(n<=2*10^9\)十分无奈,所以考虑优化。

我们来深层次挖掘一下他的式子:

\(a_i=a_{i-1}+a_{i-3}(i>3)\)

这个东西有什么用呢?

我们令一个矩阵为\(S\{3*1\}={a_i,a_{i-1},a_{i-2}}\)

那么如果我们要递推呢?

如何转移到\(a_{i+1},a_i,a_{i-1}\)呢?

再令一个矩阵\(T\{3*3\}\)表示一个转移矩阵,那么根据递推式子和矩阵乘法的原则,有一个这样子的矩阵?

\(T[3][3]={1,1,0},{0,0,1},{1,0,0}\)这个可能竖着比较好看。

\(\{1,1,0\}\)

\(\{0,0,1\}\)

\(\{1,0,0\}​\)

那么就是每一列对应着对应位置的转移,大致推导就是这样。

那么考虑简化这个东西。

\(Ans=(((S*T)*T)*T)\)

那么可以把括号拆开,就可以得出\(Ans=S*T^k\)

所以可以矩阵快速幂优化就可以AC!!!

#include
#include
#include
#include
#include
#include
#define ll long long#define re registerinline int gi(){ int f=1,sum=0;char ch=getchar(); while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();} return f*sum;}const ll Mod=1e9+7;struct matrix{ ll a[3][3]; matrix operator*(const matrix b)const{ matrix c; for(re int i=0;i<3;i++) for(re int j=0;j<3;j++){ c.a[i][j]=0; for(re int k=0;k<3;k++) c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j]%Mod)%Mod; } return c; }}S,T;void init(){ S.a[0][0]=S.a[0][1]=S.a[0][2]=1; T.a[0][0]=T.a[0][1]=T.a[2][0]=1; T.a[1][1]=T.a[1][0]=T.a[0][2]=T.a[2][1]=T.a[2][2]=0; T.a[1][2]=1; }int n;int main(){ int t=gi(); while(t--){ n=gi(); if(n<=2){ puts("1");continue; } init(); n-=3; while(n){ if(n&1)S=S*T; T=T*T;n>>=1; } printf("%lld\n",S.a[0][0]); } return 0;}

转载于:https://www.cnblogs.com/biscuit46/p/9871942.html

你可能感兴趣的文章
imx6 18bit display
查看>>
Spring静态属性注入
查看>>
实验10:指针2
查看>>
【转】hibernate缓存:一级缓存和二级缓存
查看>>
第二个spring冲刺第3天
查看>>
AwSnap:让全版本(Windows、iOS、Android)Chrome浏览器崩溃的有趣漏洞
查看>>
线段树合并学习笔记
查看>>
AndroidAutoLayout
查看>>
样本不均衡下的分类损失函数
查看>>
node启动服务后,窗口不能关闭。pm2了解一下
查看>>
vsCode 改变主题
查看>>
【vijos】【树形dp】佳佳的魔法药水
查看>>
聚合新闻头条
查看>>
Ubuntu 关闭锁屏界面的 on-screen keyboard
查看>>
凸优化学习笔记
查看>>
使用ehcache-spring-annotations开启ehcache的注解功能
查看>>
Charles设置HTTPS抓包
查看>>
NGUI出现Shader wants normals, but the mesh UIAtlas doesn&#39;t have them
查看>>
Boost.Asio c++ 网络编程翻译(14)
查看>>
Codeforces Round #306 (Div. 2) D.E. 解题报告
查看>>