零化多项式

零化多项式

定义:

矩阵定义

设域为 \(\mathbb{F}\),在一个线性空间 \(\mathbb{F}^n\) 上的线性变换 \(T:V\to V\)(域为 \(\mathbb{F}\))。

若有在域 \(\mathbb{F}\) 上的多项式 \(F(z)=\sum f_iz^i\) 满足:

\[F(T)=\sum T^iz^i=0 \]

那么称 \(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)$,满足:

\[\forall n\ge d,\sum_{i=0}^da_{n-i}f_i=0 \]

则称呼它为序列 \(a\) 的零化多项式,最小多项式定义相仿。

有必要指出的是:

  1. 根据递推数列 \(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\),这是一个零化多项式。

  2. 事实上可以看到,序列 \(a\)特征方程(也称呼为特征多项式)事实上在描述 \(z^d=\sum_{i=1}^dz^{d-i}g_i\)

那么可以看出,按递推关系得到的零化多项式 \(F(z)=\sum f_iz^{d-i}\) 与特征方程正好呈现 一致的特点。

注意这里看似有些别扭的 \(F\) 定义是为了下面的统一性。

值得注意的是:

  1. 在 Berlekamp-Massey 给出的输出中给出的是 \([g_1,g_2\dots g_d]\)
  2. 在 Bostan-Mori 中使用的分母多项式 \(Q(z)=\sum z^if_i\)\(f_i=[i=0]-g_i\),也就是和零化多项式呈现系数颠倒
  3. 下面请仔细注意这两种系数的特点。

两种定义的联系

对于递推序列 \([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\),注意到每一行只有很少的元素,按每一行展开转化子问题,会容易计算很多(子结构)。

应用

  1. 将问题表达为线性组合 \(T\)(一般会得到矩阵或者序列)
  2. 利用各种算法求出其特征多项式(零化多项式) \(F(T)\)
  3. 那么就可以将 \(T^m\) 表达为更低项的计算,进而利用各类技术计算答案。

Bostan-Mori 算法求解常系数齐次线性递推远处项

详见link

将简单 DP 转移看作常系数线性递推,利用零化多项式压复杂度

对于简单的一维的序列 \(dp\),显然可以直接用上面那个办法。

二维dp的话(可以将更高维进行编号压到二维),有:

\[\mathbf{dp_i}\times M=\mathbf{dp_{i+1}} \]

\(\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)\)

零化多项式求法
  1. 直接对矩阵 \(M\) 求特征多项式,复杂度 \(O(k^4)\sim O(k^3)\)

  2. 利用随机投影法(在取模意义下)

    随机向量 \(\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 $ 同样可以辗转相除法,每次去掉最高位。

  3. 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))\)

这样的话,就能计算答案:

\[\mathbf{dp_n}=\sum_{i=0}^{d-1} \mathbf{dp_i}b_i \]

这一部分复杂度是 \(O(d\log d\log n+dk)\)

该问题总复杂度:

\[O(d\log d\log n+dk+d·trans) \]

如果使用 Bostan-Mori 算法也不无不可:注意到运算一直是向量与标量的运算,连 NTT 也不例外。

那么就可以计算了,但复杂度稍劣,为 \(O(dk\log d\log n)\)

\(d\) 显著小于 \(k\) 时,该方法用处很大

注意到用取模法计算是支持多组询问的,设询问有 \(T\) 组,复杂度是:

\[O(d·trans+Td\log d\log n+Tdk) \]

显著优于矩阵快速幂的 \(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,但我们声称:

  1. \((z-1)|F(z)\),则前缀和序列的特征方程同样是 \(F(z)\),也就是这时候仅有初值改变,递推关系不变。
  2. 否则是 \((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)\) 一样。

当然这个可以轻易扩展到高阶的情况。

posted @ 2026-01-21 11:02  spdarkle  阅读(3)  评论(0)    收藏  举报