多项式全家桶

传送门:FFT 学习笔记NTT 学习笔记

分治 FFT

例题

给定序列 \(\{g_{n - 1}\}\),对于序列 \(\{f_n\}\),有:

\[f_n = \begin{cases} 1 & n = 1 \\ \sum\limits_{j=1}^{n-1} f_j g_{i - j} & n > 1 \end{cases} \]

求出 \(i = 1, 2, \cdots, n\)\(f_i\)\(998244353\) 取模的结果。

简单的分治应用,就像用 CDQ 分治做 DP 那样,考虑对序列 \(f\) 分治。即对于一个分治区间 \([l, r)\),考虑先递归左边计算出左边的 \(f\) 值,接着算左边区间乘上 \(g\) 对右边的贡献,最后递归右边。

而对于一些类似于 \(f_n = -\frac{1}{n}\sum\limits_{i = 1}^{n - 1} f_i g_{n - i}\) 的计算,可以发现递归到底层(即 \(l + 1 = r\) 时)是按照从左往右的顺序,于是在底层时再把 \(f\) 的值处理了就可以了。

时间复杂度为 \(T(n) = 2T(\frac{n}{2}) + \mathcal{O}(n \log n)\),根据主定理可得 \(T(n) = \mathcal{O}(n \log^2 n)\)

多项式牛顿迭代

泰勒展开

对于一个非多项式函数,有时我们难以去分析和计算它,这时候我们可以用泰勒展开。泰勒展开其实就是用一个多项式函数 \(f\) 去拟合一个函数 \(g\),其做法是:

  • 选择一个拟合点 \(x_0\)
  • 如果 \(f = g\),那么在 \(x_0\) 点的值应该相等,故 \(f(x_0) = g(x_0)\)
  • 如果 \(f = g\),那么在 \(x_0\) 点的变化趋势应该相同,故 \(f'(x_0) = g'(x_0)\)
  • 如果 \(f = g\),那么在 \(x_0\) 点的导函数的变化趋势应该相同,故 \(f''(x_0) = g''(x_0)\)
  • \(\cdots\)

根据这种思想,我们得到了泰勒展开式:

\[g(x) = \sum_{n \ge 0} \frac{1}{n!} f^{(n)}(x_0) (x - x_0)^n \]

特别地,取拟合点 \(x_0 = 0\) 时得到麦克劳林展开式:

\[g(x) = \sum_{n \ge 0} \frac{1}{n!} f^{(n)}(0) x^n \]

牛顿迭代

牛顿迭代可以推导出多项式的很多公式,通过倍增法可以 \(\mathcal{O}(n \log n)\) 地对多项式操作。

首先考虑实数域 \(\mathbb{R}\) 上的牛顿迭代,牛顿迭代用于求出函数 \(f(x)\) 的零点,即 \(f(x) = 0\) 的解。流程为:

  • 最开始取一个点 \(x_0\)
  • 只取泰勒展开的前两项,有方程 \(f(x_1) = f(x_0) + f'(x_0)(x_1 - x_0) = 0\),得到公式 \(x_1 = x_0 - \frac{f(x_0)}{f'(x_0)}\) 从而求得 \(x_1\)
  • \(x_1\) 继续往下迭代:\(x_2 = x_1 - \frac{f(x_1)}{f'(x_1)}\)
  • \(x_{i + 1} = x_i - \frac{f(x_i)}{f'(x_i)}\)
  • \(\cdots\)

由于泰勒展开每次求导都会使拟合的函数图像更接近原函数,所以 \(x_{i + 1}\) 一定比 \(x_i\) 更接近 \(0\) 点。

应用:求解 \(n\) 的平方根,可以构造函数 \(f(x) = x^2 - n\),运用牛顿迭代求解其零点,有 \(x_{i + 1} = x_i - \frac{x_i^2 - n}{2x_i} \Rightarrow x_{i + 1} = \frac{1}{2}(x_i - \frac{n}{x_i})\)。(其实就是每次求 \(x_i\) 点的切线方程的解)

现在考虑在多项式域 \(\mathbb{F}\) 上的牛顿迭代,仍然考虑在 \(f_0\) 处的泰勒展开:

\[F(f) = \sum_{k \ge 0} \frac{1}{k!} F^{(k)}(f_0)(f - f_0)^n \]

我们想要求 \(F(f) \equiv 0 \pmod{x^N}\) 的解,设解为 \(f_a\)。假设 \(F(f_0) \equiv 0 \pmod{x^n}\),则 \(f_0 \equiv f_a \pmod{x^{n}}\)。在 \(f_0\) 点处泰勒展开,那么就有:

\[F(f_1) \equiv F(f_0) + F'(f_0)(f_1 - f_0) \equiv 0 \pmod {x^{2n}} \]

省略了 \(k \ge 2\) 的项的原因是,因为有 \(f_1 \equiv f_a \pmod {x^{2n}}\)\(f_0 \equiv f_a \pmod {x^{n}}\),故 \(f_1 - f_0 \equiv 0 \pmod {x^n}\),所以当 \(k \ge 2\)\((f_1 - f_0)^k \equiv 0 \pmod {x^{kn}}\)

故可以推出 \(f_1 \equiv f_0 - \frac{F(f_0)}{F'(f_0)} \pmod {x^{2n}}\)。我们只需要最开始构造出 \(f_0\) 使其满足 \(F(f_0) \equiv 0 \pmod{x}\),接着不断迭代,直到 \(n \ge N\) 时,我们就能求出原方程的解。

多项式牛顿迭代有下面几个应用。

多项式求逆

目标是求得多项式 \(g(x)\) 的逆多项式 \(g^{-1}(x)\),构造函数 \(F(f) = f^{-1} - g\),显然有 \(F(\frac{1}{g_0}) \equiv (\frac{1}{g_0})^{-1} - g \equiv 0 \pmod{x}\)。根据牛顿迭代,有:

\[\begin{aligned} f_1 \equiv f_0 + \frac{f_0^{-1} - g}{f_0^{-2}} &\pmod {x^{2n}} \\ f_1 \equiv f_0(2 - f_0g) &\pmod {x^{2n}} \end{aligned} \]

时间复杂度 \(\mathcal{O}(n \log n)\)

多项式开根

要求 \(\sqrt{g(x)}\),于是构造函数 \(F(f) = f^2 - g\),有 \(F(\sqrt{g_0}) \equiv 0 \pmod{x}\)。根据牛顿迭代,有:

\[\begin{aligned} f_1 \equiv f_0 - \frac{f_0^2 - g}{2f_0} & \pmod{x^{2n}} \\ f_1 \equiv \frac{1}{2}(f_0 + f_0^{-1}g) & \pmod{x^{2n}} \end{aligned} \]

时间复杂度 \(\mathcal{O}(n \log n)\)

多项式 \(\ln\)

这个可以不用多项式牛顿迭代,直接推式子:

\[\ln f = \int \text{d} \ln f = \int f^{-1} \text{d}x \]

于是求导、求逆、积分即可,时间复杂度 \(\mathcal{O}(n \log n)\)

多项式 \(\exp\)

要求 \(\exp g\),构造函数 \(F(f) = \ln f - g\),有 \(g_0 = 0\),故 \(F(1) \equiv 0 \mod{x}\)。根据牛顿迭代,有:

\[\begin{aligned} f_1 \equiv f_0 - \frac{\ln f_0 - g}{f_0^{-1}} &\pmod {x^{2n}} \\ f_1 \equiv f_0(1 - f_0 + g) &\pmod {x^{2n}} \end{aligned} \]

时间复杂度 \(\mathcal{O}(n \log n)\)

多项式快速幂

\(g_0 = 1\),那么 \(g\)\(k\) 次幂可以这样得出:

\[g^k = \exp (k \ln g) \]

对于 \(g_0 \ne 1\) 的情况,找出最低次项把它提出来即可。

对于 \(k \ge mod\) 的情况,有 \(g^k \equiv g^{k \bmod (p - 1)} \pmod {x^n}\)

时间复杂度 \(\mathcal{O}(n \log n)\)

posted @ 2025-01-10 00:39  CTHOOH  阅读(46)  评论(0)    收藏  举报