原文链接www.cnblogs.com/zhouzhendong/p/Cayley-Hamilton.html

Cayley-Hamilton定理与矩阵快速幂优化、常系数齐次线性递推优化

引入

在开始本文之前,我们先用一个例题作为引入。

  • 给定一个 \(n \times n\) 的矩阵 \(M\) , 求 \(M ^ k\) 。
  • \(n\leq 50, k\leq 10 ^ {50000}\) 。

注意到 \(n\) 十分小,但是 $ \log k$ 非常大。如果使用传统的矩阵快速幂,时间复杂度为 \(O(n ^ 3 \log k )\) ,难以接受。

但是运用 Cayley-Hamilton定理 来优化矩阵快速幂,可以做到 \(O(n ^ 4+n^2\log k)\) 甚至更优秀的复杂度\(^1\)。

  1. cly 说他看到有人说可以优化到 \(O(n^3 + n^2 \log k)\) 。但是不知道怎么优化。

Cayley-Hamilton定理

设 \(M\) 为一个 \(n\) 阶矩阵,定义矩阵 \(M\) 的特征多项式

\[f(x) = |xE-M| = x ^ n + c_1x^{n-1} + c_2 x ^{n-2} + \cdots + c_{n-1}x + c_n
\]

其中 \(x\) 可以属于一些域,包括但不限于复数域。

由于 \(|ME - M| = |0| = 0\) ,所以

\[f(M) = M ^ n + c_1 M ^ {n-1} + c_2 M ^ {n-2} + \cdots + c_{n-1} M + c_n = 0
\]

矩阵快速幂

如果我们得到了 \(f(M)\) ,那么,将任意一个矩阵减去任意倍数的 \(f(M)\) 后值不变。

即:令 \(g(x) = x^k\),

\[M ^ k = (g \bmod f)(M)
\]

考虑如何求解 \(g \bmod f\)。

类比对整数域下取模的快速幂做法,考虑对多项式 \(x\) 做快速幂,对 \(f\) 取模,直接实现的时间复杂度为 \(O(n ^ 2 \log k)\),如果采用 \(FFT\) 优化乘法,并利用多项式取模的做法实现取模,那么时间复杂度为 \(O(n \log n \log k)\) 。

接下来我们来讨论如何求 \(f(M)\) 。

将 \(n\) 个值代入 \(x\) 求行列式,再插值得到 \(f(M)\) ,时间复杂度 $O(n ^ 4) $ ,注意这里要求代入的值存在乘法逆元。

得到 \(g \bmod f\) 之后只需要将所有 \(M\) 的幂代入即可得到 $M ^ k $,这里时间复杂度也是 $O(n ^ 4) $ 。

综上所述,总时间复杂度 \(O(n ^ 4)\) 。

线性递推

回归本源,当我们要做矩阵快速幂的原因,往往是为了快速实现线性递推。由于线性递推问题存在特殊性,我们可以通过 Cayley-Hamilton定理 来得到更优秀的做法。

假设线性递推数列满足

\[b_n = \sum_{i = 1} ^ k b_{n-k} a _i
\]

我们将线性递推的矩阵写出来:

\[\begin {eqnarray*}
f(x) &=& |xE - M| \\
&=& \left |
\begin {bmatrix}
x & -1 & 0 & 0 & \cdots & 0 \\
0 & x & -1 & 0 & \cdots & 0 \\
0 & 0 & x & -1 & \cdots & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots \\
0 & 0 & 0 & 0 & \cdots & -1 \\
-a_k & -a_{k-1} & -a_{k-2} & -a_{k-3} &\cdots & x-a_1
\end{bmatrix}
\right |\\
& = & x\left |
\begin {bmatrix}
x & -1 & 0 & 0 & \cdots & 0 \\
0 & x & -1 & 0 & \cdots & 0 \\
0 & 0 & x & -1 & \cdots & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots \\
0 & 0 & 0 & 0 & \cdots & -1 \\
-\frac{a_k}{x}-a_{k-1} & -a_{k-2} & -a_{k-3} & a_{k-4} &\cdots & x-a_1
\end{bmatrix}
\right |\\
& = & x^2\left |
\begin {bmatrix}
x & -1 & 0 & 0 & \cdots & 0 \\
0 & x & -1 & 0 & \cdots & 0 \\
0 & 0 & x & -1 & \cdots & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots \\
0 & 0 & 0 & 0 & \cdots & -1 \\
-\frac{a_k}{x^2}-\frac{a_{k-1}}x-a_{k-2} & -a_{k-3} & a_{k-4} & a_{k-5}&\cdots & x-a_1
\end{bmatrix}
\right |\\
&\Large\vdots &\\
& = & x ^ {k-1} \cdot\left (x - \sum_{i=1}^k \frac {a_i }{x^{i-1}}\right)\\
& = & x ^ k - \sum_{i=1}^{k} a _ i x ^ {k-i}
\end {eqnarray*}
\]

假设初始向量是列向量 \(B\) ,矩阵是 \(M\) ,那么

\[M =
\begin{bmatrix}
0 & 1 & 0 & 0 & \cdots & 0 \\
0 & 0 & 1 & 0 & \cdots & 0 \\
0 & 0 & 0 & 1 & \cdots & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots \\
0 & 0 & 0 & 0 & \cdots & 1 \\
a_k & a_{k-1} & a_{k-2} & a_{k-3} &\cdots & a_1
\end{bmatrix}
\]

则我们要求的是

\[(B \cdot M^{n} )[0]
\]

接下来我们来求 \(M\) 的特征多项式。

于是我们就直接得到了特征多项式的系数。

于是

\[(B \cdot M^{n} )[0]\\
= (B\cdot (x^n \bmod f(x))(M))[0]
\]

假设结果为

\[B \cdot \sum_{i=0}^{k-1}c_iM ^ i \\ = \sum_{i = 0}^ {k-1} c_i B M ^ i
\]

因为 \(B M ^ i [a] = B[a + i]\),而这里 \(i < k\),我们要求的是 \(BM^i[0]\) ,所以我们只需要知道 \(B[0] \cdots B[k-1]\) 即可。类似地,只要我们预处理 B 数列的前 \(2k\) 项,就可以得到整个 \(BM^i\) 列向量了。

求单个值的时间复杂度为 \(O(k ^ 2\log n)\) 。

模板题 BZOJ4161

代码

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof x)
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define outval(x) printf(#x" = %d\n",x)
#define outtag(x) puts("---------------"#x"---------------")
#define outarr(a,L,R) printf(#a"[%d..%d] = ",L,R);\
For(_x,L,R)printf("%d ",a[_x]);puts("")
using namespace std;
typedef long long LL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=2005*2,mod=1e9+7;
int n,k;
int a[N],b[N];
void Add(int &x,int y){
if ((x+=y)>=mod)
x-=mod;
}
void Del(int &x,int y){
if ((x-=y)<0)
x+=mod;
}
int c[N];
void Mul(int *x,int *y){
static int z[N];
clr(z);
For(i,0,k-1)
For(j,0,k-1)
Add(z[i+j],(LL)x[i]*y[j]%mod);
Fod(i,2*k-2,k){
if (!z[i])
continue;
For(j,1,k)
Add(z[i-j],(LL)a[j]*z[i]%mod);
}
For(i,0,k-1)
x[i]=z[i];
}
void GetPoly(){
static int x[N];
int y=n;
clr(x),clr(c),c[0]=x[1]=1;
for (;y;y>>=1,Mul(x,x))
if (y&1)
Mul(c,x);
}
int main(){
n=read(),k=read();
For(i,1,k)
a[i]=(read()+mod)%mod;
For(i,0,k-1)
b[i]=(read()+mod)%mod;
GetPoly();
int ans=0;
For(i,0,k-1)
Add(ans,(LL)b[i]*c[i]%mod);
cout<<ans<<endl;
return 0;
}

Cayley-Hamilton定理与矩阵快速幂优化、常系数线性递推优化的更多相关文章

  1. 矩阵乘法&矩阵快速幂&矩阵快速幂解决线性递推式

    矩阵乘法,顾名思义矩阵与矩阵相乘, 两矩阵可相乘的前提:第一个矩阵的行与第二个矩阵的列相等 相乘原则: a b     *     A B   =   a*A+b*C  a*c+b*D c d     ...

  2. HDU 3802 矩阵快速幂 化简递推式子 加一点点二次剩余知识

    求$G(a,b,n,p) = (a^{\frac {p-1}{2}}+1)(b^{\frac{p-1}{2}}+1)[(\sqrt{a} + \sqrt{b})^{2F_n} + (\sqrt{a} ...

  3. 矩阵快速幂(queue递推)

    http://acm.hdu.edu.cn/showproblem.php?pid=2604 Queuing Time Limit: 10000/5000 MS (Java/Others)    Me ...

  4. HDU4549 M斐波那契数列 —— 斐波那契、费马小定理、矩阵快速幂

    题目链接:https://vjudge.net/problem/HDU-4549 M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Li ...

  5. 2019牛客多校第五场 B - generator 1 矩阵快速幂+十倍增+二进制倍增优化

    B - generator 1 题意 给你\(x_{0}.x_{1}.a.b.b.mod\),根据\(x_{i} = a*x_{i-1} + b*x_{i-2}\)求出\(x_{n}\) 思路 一般看 ...

  6. 【矩阵乘法】【快速幂】【递推】斐波那契数列&&矩乘优化递推模板

    题目大意: F[0]=0 F[1]=1 F[n+2]=F[n+1]+F[n] 求F[n] mod 104. F[n+2] F[n+1] = 1 1 1 0 * F[n+1] F[n] 记这个矩阵为A, ...

  7. 矩阵快速幂---BestCoder Round#8 1002

    当要求递推数列的第n项且n很大时,怎么快速求得第n项呢?可以用矩阵快速幂来加速计算.我们可以用矩阵来表示数列递推公式比如fibonacci数列 可以表示为 [f(n)   f(n-1)] = [f(n ...

  8. 2017中国大学生程序设计竞赛 - 女生专场 Happy Necklace(递推+矩阵快速幂)

    Happy Necklace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  9. $bzoj1009-HNOI2008$ $GT$考试 字符串$dp$ 矩阵快速幂

    题面描述 阿申准备报名参加\(GT\)考试,准考证号为\(N\)位数\(x_1,x_2,...,x_n\ (0\leq x_i\leq 9)\),他不希望准考证号上出现不吉利的数字. 他的不吉利数字\ ...

随机推荐

  1. tcp协议close_wait与time_wait状态含义

    题目描述 1.什么是三次握手,四次挥手?为什么分别要三次与四次? 2.tcp协议中,close_wait与time_wait状态分别代表什么含义,为什么要设计这两种状态,解决了什么问题? 3.time ...

  2. dubbo源码阅读之服务引入

    服务引入 服务引入使用reference标签来对要引入的服务进行配置,包括服务的接口 ,名称,init,check等等配置属性. 在DubboNamespaceHandler中,我们可以看到refer ...

  3. jupyter安装出现问题:安装后无法打开

    jupyter安装出现问题:安装后无法打开 traitlets.traitlets.TraitError: Could not decode 'C:\Users\\xce\xa2\xcc\xf0\xd ...

  4. 用Visual Studio 2015 编写 MASM 汇编程序(二)从头开发一个Win32汇编程序

    一,建立一个VC的控制台类型的空工程: 1,从VS菜单中选择“文件”->“新建”->“项目”. 2,在新建项目中选择:“Visual c++”->"Win32"- ...

  5. 安恒pwn魔法

    魔法这是比较基础的一道栈溢出: 首先看下开启的防护机制 Checksec magicc发现只有nx防护 我们载入ida发现溢出点 Buf实际溢出空间为0x16,构造exp import time fr ...

  6. 根据域名获取ip地址

    1如何查询网站域名对应的ip地址在电脑左下角搜索cmd ,在命令提示符中输入 ping www.pm25.in在电脑左下角搜索运行,输入cmd ,在命令提示符中输入 ping www.pm25.in得 ...

  7. SQL SERVER-记录对表操作的触发器

    CREATE TRIGGER [dbo].[KNMT_LOG] ON [dbo].[KNMT] FOR UPDATE, DELETE AS ) ) ) ) DECLARE @STATMT AS VAR ...

  8. (备忘)解决用Xftp向CentOS7 传文件速度慢的问题

    问题原因:之前用XFTP上传文件的时候一直挺好的,今天突然速度特别慢,上传了一个多小时也没把一个一百兆的文件成功上传 查询过程: 1.网络原因:网络的确有点卡,但不至于这么慢吧,几K的速度,鉴于网络问 ...

  9. node-images 进行图片压缩

    前置条件:先安装images npm install images 编写代码 思路: 从指定文件夹遍历图片,执行压缩,压缩完成后放到指定文件夹中,并保持图片名无变化. var images = req ...

  10. 牛客NOIP暑期七天营-提高组1 解题报告

    https://ac.nowcoder.com/acm/contest/920#question A 构造+双指针 发现m的限制是1e5,而点数是5e4,所以不能构造太多的边,思考一下最短路树的定义. ...