多项式全家桶

求逆

考虑倍增。

若已经求出 \(A \times B' \equiv 1 \pmod {x^n}\),我们希望求出 \(B\) 使得 \(A \times B \equiv 1 \pmod {x^{2n}}\)

有:

\[B - B' \equiv 0 \pmod {x^n} \]

\[(B - B')^2 \equiv 0 \pmod {x^{2n}} \]

\[B^2 - 2 B B' + B'^2 \equiv 0 \pmod {x^{2n}} \]

两边同乘 \(A\),有:

\[B - 2B' + AB'^2 \equiv 0 \pmod {x^{2n}} \]

所以:

\[B \equiv 2B' - AB'^2 \pmod {x^{2n}} \]

注意应该倍增到最小的 \(2^t\) 使得 \(2^t \ge n\)

时间复杂度 \(O((n + \frac{n}{2} + \frac{n}{4} + \cdots) \log n) = O(n \log n)\)

带余除法

比较智慧。

考虑定义一个操作 \(A^R(x) = A(\frac{1}{x}) = \sum\limits_{i = 0}^n a_i x^{n - i}\)。其实就是把系数翻转。

那么:

\[F(x) \equiv Q(x) G(x) + R(x) \pmod{x^n} \]

\[F(\frac{1}{x}) \equiv Q(\frac{1}{x}) G(\frac{1}{x}) + R(\frac{1}{x}) \pmod{x^n} \]

\[x^n F(\frac{1}{x}) \equiv x^{n - m} Q(\frac{1}{x}) x^m G(\frac{1}{x}) + x^n R(\frac{1}{x}) \pmod{x^n} \]

\[F^R(x) \equiv Q^R(x) G^R(x) + x^{n - m + 1} R^R(x) \pmod{x^n} \]

\[F^R(x) \equiv Q^R(x) G^R(x) \pmod{x^{n - m}} \]

\[Q^R(x) \equiv F^R(x) G^R(x)^{-1} \pmod{x^{n - m}} \]

注意到 \(Q(x)\) 的最高项次数恰为 \(n - m\),所以这样即可求得 \(Q(x)\),进而求出 \(R(x)\)

时间复杂度 \(O(n \log n)\)

\(\ln\)

考虑利用多项式求导,有:

\[B(x) \equiv \ln A(x) \pmod{x^n} \]

\[B'(x) \equiv \frac{A'(x)}{A(x)} \pmod{x^n} \]

这样就能求出 \(B'(x)\),进而求出 \(B(x)\)

时间复杂度 \(O(n \log n)\)

\(\exp\)

考虑泰勒展开。对于一个光滑函数 \(g(x)\),我们有:

\[g(x) = g(x_0) + \frac{1}{1!} g'(x_0) (x - x_0) + \frac{1}{2!} g''(x_0) (x - x_0) ^ 2 + \cdots \]

考虑倍增。假设我们已经求出了 \(B_0(x)\) 使得 \(A(x) \equiv \ln B_0(x) \pmod{x^n}\),我们现在希望求出 \(B(x)\) 使得 \(A(x) \equiv \ln B(x) \pmod{x^{2n}}\)。那么令 \(g\)\(\ln\)\(x\)\(B(x)\)\(x_0\)\(B_0(x)\)

注意到 \(B(x) \equiv B_0(x) \pmod{x^n}\),所以 \((B(x) - B_0(x))^2 \equiv 0 \pmod{x^{2n}}\)。所以有:

\[\ln(B(x)) \equiv \ln(B_0(x)) + \frac{B(x) - B_0(x)}{B_0(x)} \pmod{x^{2n}} \]

\[B_0(x) (A(x) - \ln(B_0(x)) + 1) \equiv B(x) \pmod{x^{2n}} \]

做一次 \(\ln\) 和乘法即可。

注意一些实现细节,比如 \(\ln(B_0(x))\) 应该在 \(\bmod x^{2n}\) 意义下算。

时间复杂度 \(O((n + \frac{n}{2} + \frac{n}{4} + \cdots) \log n) = O(n \log n)\)

快速幂

\[B(x) \equiv A(x)^k \pmod {x^n} \]

\[\ln B(x) \equiv k \ln A(x) \pmod {x^n} \]

\[B(x) \equiv e^{k \ln A(x)} \pmod {x^n} \]

所以先 \(\ln\)\(\exp\) 即可。

注意为了保证 \([x^0]A(x) = 1\) 需要先提公因式 \(ax^p\)

开方

相当于 \(k \equiv \frac{1}{2}\) 的快速幂。

为了保证 \([x^0]A(x) = 1\) 仍然提公因数 \(a\)(因为这项一定不是 \(0\))。那么求一个 \(a\) 的二次剩余再乘回去即可。

多点求值

发现 \(F(x_0) = F(x) \bmod (x - x_0)\)。因为 \(F(x) = Q(x) G(x) + R(x)\),而且 \(G(x_0) = 0\)

考虑分治求 \(F(x) \bmod \prod\limits_{i = l}^r (x - a_i)\)。每次把 \(F(x)\)\(\prod\limits_{i = l}^r (x - a_i)\) 取模即可。这样时间复杂度是 \(O(n \log^2 n)\),但是因为每次递归都要多项式取模所以常数很大。

发现因为余数只有常数项,并且 \(R(x) = F(x) - Q(x) G(x)\),所以我们也只用关心 \(F(x), G(x), Q(x)\) 的常数项,即 \(F^R(x), G^R(x), Q^R(x)\)\(n - 1\) 次项。

所以我们一开始先令 \(G(x) = \prod\limits_{i = 1}^n (x - a_i)\) 并算出 \(Q^R(x)\),然后分治左区间则乘上右半边的乘积,分治右区间则乘上左半边的乘积。并且注意到递归到 \([l, r]\) 后之后乘的多项式次数 \(< r - l + 1\),所以可以只保留后面 \(r - l + 1\) 项,这样复杂度就对了,还是 \(O(n \log^2 n)\)

快速插值

考虑拉格朗日插值,答案即为

\[\sum\limits_{i = 1}^n y_i \prod\limits_{j \ne i} \frac{x - x_j}{x_i - x_j} \]

先考虑每个 \(i\) 对应的分母 \(z_i\)。设 \(F(x) = \prod\limits_{i = 1}^n (x - x_i)\),相当于要算 \(\frac{F(x)}{x - x_i}\) 代入 \(x_i\) 后的值。但是此时分子和分母都是 \(0\)。根据洛必达法则,此时可以算 \(\frac{F'(x)}{(x - x_i)'} = F'(x)\) 代入 \(x_i\) 后的值。于是多点求值即可。

再考虑算整个式子。仍然可以分治,分治的时候算 \(\sum\limits_{i = l}^r \frac{y_i}{z_i} \prod\limits_{l \le j \le r \land j \ne i} (x - x_j)\)。只需要左边的答案乘上右半边区间多项式的乘积,加上右边的答案乘上左半边区间多项式的乘积即可。时间复杂度 \(O(n \log^2 n)\)

常系数齐次线性递推

考虑构造矩阵 \(M\),其中 \(M_{0, i} = a_{i + 1}\)\(M_{i + 1, i} = 1\),其余位置为 \(0\)。那么:

\[\begin{bmatrix} f_{n + k - 1} \\ f_{n + k - 2} \\ \vdots \\ f_n \end{bmatrix} = M^n \begin{bmatrix} f_{k - 1} \\ f_{k - 2} \\ \vdots \\ f_0 \end{bmatrix} \]

\(M\) 的特征多项式为 \(\varphi(x) = x^k - a_1 x^{k - 1} - a_2 x^{k - 2} - \cdots - a_k x^0\)

\(x^n = Q(x) \varphi(x) + R(x)\),那么 \(M^n = Q(M) \varphi(M) + R(M)\)。又因为由 Cayley-Hamilton 定理得 \(\varphi(M) = 0\),所以 \(M^n = R(M)\)

\(R(x) = \sum\limits_{i = 0}^{k - 1} r_i x^i\),列向量 \(F = \begin{bmatrix} f_{k - 1} \\ f_{k - 2} \\ \vdots \\ f_0 \end{bmatrix}\)。那么:

\[\begin{aligned} M^n & = \sum\limits_{i = 0}^{k - 1} r_i M^i \\ M^n F & = \sum\limits_{i = 0}^{k - 1} r_i (M^i F) \\ (M^n F)_{k - 1} & = \sum\limits_{i = 0}^{k - 1} r_i (M^i F)_{k - 1} \\ f_n & = \sum\limits_{i = 0}^{k - 1} r_i f_i \end{aligned} \]

于是剩下的问题是求 \(R(x)\),也就是 \(x^n \bmod \varphi(x)\)。直接多项式快速幂即可,每次次数超过 \(k\) 了就对 \(\varphi(x)\) 取模。

时间复杂度 \(O(k \log k \log n)\)

posted @ 2024-04-19 22:45  zltzlt  阅读(39)  评论(0)    收藏  举报