零化多项式
零化多项式
定义:
矩阵定义
设域为 \(\mathbb{F}\),在一个线性空间 \(\mathbb{F}^n\) 上的线性变换 \(T:V\to V\)(域为 \(\mathbb{F}\))。
若有在域 \(\mathbb{F}\) 上的多项式 \(F(z)=\sum f_iz^i\) 满足:
那么称 \(F(z)\) 为 \(T\) 的零化多项式。 \(F(T)\) 是一个新的线性变换(零变换)。
- 特别地,若 \(T\) 为一个矩阵,那么就称 \(F(z)\) 零化矩阵 \(T\)。
找到一个多项式 \(F(z)\),满足将变量替换为操作 “T” 后,整个线性组合的和为零。
-
特征多项式:设 \(F(\lambda)=\det(\lambda I - T)\)(这是函数的点值表示法),则 \(F(T)=0\),注意这是零矩阵的意思。
其正确性源自 Cayley–Hamilton 定理。
它说明一个矩阵的特征多项式一定是它的零化多项式。
求法:带入 \(|T|\) 个 \(\lambda\),再用高斯消元 \(O(|T|^3)\) 计算,最后用拉格朗日插值还原多项式 \(F(\lambda)\)。
时间复杂度 \(O(|T|^4)\)。
\(\deg F(\lambda)\le |T|\)
有上海森堡矩阵的办法,详见link,待补。
以下记矩阵 \(T\) 的特征多项式为 \(\chi_T(z)\)
-
最小多项式:记矩阵 \(T\) 的最小多项式为 \(\mu_T(z)\)。它是满足阶数最小的,首项为 \(1\) 的零化多项式。
\(T\) 的最小多项式满足,任意 \(T\) 的零化多项式都是 \(\mu_T(z)\) 的倍数。
换句话说,\(\mu_T(z)\) 整除任意 \(T\) 的零化多项式。
\(\deg \mu_T(z)\le |T|\)。
序列定义
对于递推数列 \(\lbrace a\rbrace_{n\ge 0}\),若存在阶为 \(d\) 的多项式 $ F(z)$,满足:
则称呼它为序列 \(a\) 的零化多项式,最小多项式定义相仿。
有必要指出的是:
-
根据递推数列 \(a\) 的递推关系 \(a_n=\sum_{i=1}^da_{n-i}g_i\) 足以得到多项式 \(F(z)=\sum z^{d-i}f_i=\sum z^{d-i}([i=0]-g_i)\),\(g_0=0\),这是一个零化多项式。
-
事实上可以看到,序列 \(a\) 的特征方程(也称呼为特征多项式)事实上在描述 \(z^d=\sum_{i=1}^dz^{d-i}g_i\)。
那么可以看出,按递推关系得到的零化多项式 \(F(z)=\sum f_iz^{d-i}\) 与特征方程正好呈现 一致的特点。
注意这里看似有些别扭的 \(F\) 定义是为了下面的统一性。
值得注意的是:
- 在 Berlekamp-Massey 给出的输出中给出的是 \([g_1,g_2\dots g_d]\)
- 在 Bostan-Mori 中使用的分母多项式 \(Q(z)=\sum z^if_i\),\(f_i=[i=0]-g_i\),也就是和零化多项式呈现系数颠倒
- 下面请仔细注意这两种系数的特点。
两种定义的联系
对于递推序列 \([a_{n-d+1}\dots a_n]\times M =[a_{n-d+2}\dots a_{n+1}]\)。
这样的矩阵 \(M\) 的特征多项式正好是递推序列 \(a\) 的特征方程,也就是零化多项式。
递推式(向后写法):
\[a_n = \sum_{i=1}^{d} f_i \cdot a_{n-i} = f_1 a_{n-1} + f_2 a_{n-2} + \cdots + f_d a_{n-d} \]状态向量(行向量,从旧到新):
\[\mathbf{v}_n = [a_{n-d+1}, a_{n-d+2}, \ldots, a_n] \]转移:
\[\mathbf{v}_n \cdot M = \mathbf{v}_{n+1} \]\[M = \begin{pmatrix} 0 & 0 & 0 & \cdots & 0 & f_d \\ 1 & 0 & 0 & \cdots & 0 & f_{d-1} \\ 0 & 1 & 0 & \cdots & 0 & f_{d-2} \\ \vdots & & \ddots & & \vdots & \vdots \\ 0 & 0 & \cdots & 1 & 0 & f_2 \\ 0 & 0 & \cdots & 0 & 1 & f_1 \end{pmatrix} \]最后一列从下到上是 \(f_1, f_2, \ldots, f_d\)。
\[\chi_M(x) = \det(xI - M) = x^d - f_1 x^{d-1} - f_2 x^{d-2} - \cdots - f_d \]计算方法:写出 \(xI-M\),注意到每一行只有很少的元素,按每一行展开转化子问题,会容易计算很多(子结构)。
应用
- 将问题表达为线性组合 \(T\)(一般会得到矩阵或者序列)
- 利用各种算法求出其特征多项式(零化多项式) \(F(T)\)
- 那么就可以将 \(T^m\) 表达为更低项的计算,进而利用各类技术计算答案。
Bostan-Mori 算法求解常系数齐次线性递推远处项
详见link
将简单 DP 转移看作常系数线性递推,利用零化多项式压复杂度
对于简单的一维的序列 \(dp\),显然可以直接用上面那个办法。
二维dp的话(可以将更高维进行编号压到二维),有:
则 \(\mathbf{dp_n}=\mathbf{dp_0}\times M^n\)。
则所有 \(\mathbf{dp_i}\) 有公共零化多项式,它的阶数不超过 \(\deg\mathbf{dp_i}\)。
(就是 \(M\) 的零化多项式)
初值可能需要特判。
以下设 \(k\) 为阶数,设单次转移复杂度为 \(O(trans)\)。
如果矩阵 \(M\) 比较稀疏或者特殊,trans 会很小,可以降低复杂度。
case1 答案是标量
若我们只是要求 \(\mathbf{dp_n}\times \mathbf{v^T}\) 这个标量或者求 \(\mathbf{dp_n}·\mathbf{v}\) 这个标量。
那么可以直接跑 \(2k\) 次转移算出 \(dp_0\sim dp_{2k}\) 所对应的标量,扔进 BM 里面跑递推式再用上一个办法即可。
复杂度 \(O(k^2+trans·k)\)。
case2 答案是向量
如果我们确定要求出 \(\mathbf{dp_n}\),该怎么办呢?
所有 \(\mathbf{dp_i}\) 有公共零化多项式,它的阶数不超过 \(k\),那么只要我们求出这个公共零化多项式,就可以使用上一个办法求出 \(\mathbf{dp_n}\) 了。
先求出 \(\mathbf{dp_{0}\sim dp_{2k}}\)。
如果你自信零化多项式阶数很小,例如只有 \(d\),那么只需要求出前 \(2d\) 项
复杂度 \(O(d·trans)\)。
零化多项式求法
-
直接对矩阵 \(M\) 求特征多项式,复杂度 \(O(k^4)\sim O(k^3)\)
-
利用随机投影法(在取模意义下)
随机向量 \(\mathbf{r}\),设 \(a_i=\mathbf{dp_i·r}\),将 \(a_i\) 扔进BM里算出系数。
这一步是 \(O(dk+d^2)\) 的。这样我们就得到了递推系数 \([g_1,g_2\dots g_d]\),也就有了零化多项式 \(G(z)=\sum z^ig’_{d-i}\),规定 \(g_0=1,g_i'=-g_i\)。
正确率:根据 Schwartz–Zippel 引理:失败的概``率只有:\(\frac{1}{p}\)
如果不放心,可以取多个,然后对得到的所有零化多项式 \(G(z)\) 求 \(\operatorname{lcm}\) 即可。
\(\operatorname{lcm}(F(z),G(z))=\frac{F(z)\times G(z)}{\gcd(F(z),G(z))}\)
$\gcd $ 同样可以辗转相除法,每次去掉最高位。
-
100% 正确但是高复杂度的做法,对每个 \(i\in [0,k-1]\),拿出 \(\mathbf{dp_j}\) 的第 \(i\) 项组成 \(k\) 个向量,分别跑 BM,再求 \(\operatorname{lcm}\)。
注意多项式 \(\operatorname{lcm}\) 别把系数搞反了。
求出 \(\mathbf{dp_n}\)
这时候我们已经知道零化多项式 \(G(z)\) 了。
同样的,我们再扩展 link 中提到的第二种上个问题的解决办法。
求出 \(z^n\equiv B(z)(\bmod G(z))\)。
这样的话,就能计算答案:
这一部分复杂度是 \(O(d\log d\log n+dk)\)。
该问题总复杂度:
如果使用 Bostan-Mori 算法也不无不可:注意到运算一直是向量与标量的运算,连 NTT 也不例外。
那么就可以计算了,但复杂度稍劣,为 \(O(dk\log d\log n)\)。
当 \(d\) 显著小于 \(k\) 时,该方法用处很大
注意到用取模法计算是支持多组询问的,设询问有 \(T\) 组,复杂度是:
显著优于矩阵快速幂的 \(O(k^3\log n+Tk^2\log n)\)。
用途
- 自动机/图论走路计数等矩阵确定的情形。
求前缀和
已知序列 \(a\) 满足递推关系,其零化多项式/特征方程为阶数为 \(d\) 的多项式 \(F(z)\)。
则其前缀和序列 \(s_i=\sum_{j=0}^ia_j\) 通常也满足递推关系,且阶数不超过 \(d+1\)。
虽然暴力的办法是跑出 \(s\) 的前 \(2(d+1)\) 项做 BM,但我们声称:
- 若 \((z-1)|F(z)\),则前缀和序列的特征方程同样是 \(F(z)\),也就是这时候仅有初值改变,递推关系不变。
- 否则是 \((z-1)F(z)\),这时候初值改变,并且多加一个初值 \(s_d\)。
说明 \(z-1\) 的来头:
在 Bostan-Mori 算法的过程中:
这里需要改一下变量描述:
目标序列 \(f\),生成函数 \(F(z)\)
转移系数 \(g\),生成函数 \(G(z)=\sum z^ig_i\),注意这是特征方程系数颠倒后的多项式
则 \(F(z)G(z)=R(z)\),其中 \(R(z)\) 是只拿初始值与 \(G\) 做卷积后仅保留 \(0\sim d-1\) 项的结果。
那么\(F(z)=\frac{R(z)}{G(z)}\),因此乘以前缀和算子 \(\frac{1}{1-z}\):
\[F(z)\frac{1}{1-z}=\frac{R(z)}{G(z)(1-z)} \]又因为 \(G\) 是系数颠倒后的结果,因此颠倒回来相当于乘上了 \({1-\frac{1}{z}}=\frac{1}{z}(z-1)\),而 \(\frac{1}{z}\) 又被颠倒回来多出的那个阶数抵消掉了。
因此看上去就像特征方程乘上 \((z-1)\) 一样。
当然这个可以轻易扩展到高阶的情况。

浙公网安备 33010602011771号