多项式基础
多项式基础
Lagrange 插值法
Lagrange 插值 I
给定 \(n\) 个点 \((x_i,y_i)\),求出一个 \((n-1)\) 次多项式经过所有的点。
对 \(998,422,353\) 取模。\(n\leq 2\times 10^3\)。
我们考虑构造 \(f_i(x)\) 表示 \(\forall j\neq i, f(x_j)=0\),且 \(f(x_i)=y_i\) 的函数。
首先考虑如何满足第一个条件。不难想到只要把 \((x-x_j)\) 乘起来就行了。也就是
然后考虑如何满足第二个条件。将 \(x_i\) 代入,我们发现此时函数值为 \(\prod_{j\neq i}(x_i-x_j)\)。那么我们只需要给刚才那个函数乘上 \(\displaystyle \frac{y_i}{\prod_{j\neq i}(x_i-x_j)}\) 就可以了。
于是我们不难得到了
将 \(n\) 个函数加起来,我们得到
不难发现这个函数符合题意。于是就做完了。
题目要求的是代入一个点求值,可以直接在循环的时候算。
时间复杂度 \(\Theta(n^2)\)。
Lagrange 插值 II
本题需要多项式基础。
做法 1:卷积
给定 \(f(0),f(1) \dots f(n)\),求 \(f(m),f(m+1) \dots f(m+n)\)。
\(n \le 160000\)。
朴素的 \(\Theta(n^2)\) 插值显然无法通过。考虑优化。
注意到本题给的点值很有特点(是 \([0,n]\cap \mathbb{Z}\))。我们将 \(x+k\) 代入朴素的插值公式中
即
注意下面的 \(\prod_{j\neq i}(i-j)\) 项,其显然等于
即
预处理后是可以 \(\Theta(1)\) 求出的。
考虑分子。其显然等于
即
于是
暂时忽略前面的系数,注意到后面的式子有点像卷积的形式,考虑卷积。
考虑利用 \(c_{n+k}\) 算出 \(f(m+k)\)。那么
不难发现当 \(i\in [0,n]\) 时,只需要令
即可。当 \(i\gt n\) 时,令 \(a_i=0, b_i=\dfrac{1}{(i+m-n)!}\) 即可。
时间复杂度 \(\Theta(n\log n)\)。
做法 2:转下降幂
(下降幂的定义在后面)
我们有下降幂的二项式定理
假设我们已经得到了 \(f\) 对应的下降幂多项式,即 \(f=\sum a_ix^{\underline{i}}\),现在求 \(f(x+k)\)。
考虑后面的式子如何用卷积求。
卷积的上界是 \(n-j\),这意味着我们实际上要取的是卷积后结果的第 \(n-j\) 项。注意到
于是可以令 \(a_i=\dfrac{k^{\underline{i}}}{i!}\),\(b_{n-j-i}=a_{i+j}\cdot {(i+j)!}\)。
令 \(i=n-i\),我们得到 \(b_{i-j}=a_{n-i+j}\cdot (n-i+j)!\)
再令 \(i=i+j\),我们得到 \(b_{i}=a_{n-i}\cdot (n-i)!\)
我们可以愉快地做卷积了。
于是,我们
-
求出 \(f\) 的下降幂多项式 \(F\)。
-
卷积求出平移后的系数。
-
将 \(F'\) 转为普通多项式 \(f'\)。
关于如何将 \(f\) 的点值转为下降幂多项式,请参阅本人的多项式基础 blog。
一共要做三次多项式乘法,时间复杂度 \(\Theta(n\log n)\)。
下降幂多项式的特殊插值
也就是,给定 \(f(0),f(1),\cdots,f(n)\),求出 \(f=\sum_{k=0}^n a_kx^{\underline{k}}\),使得满足要求。
我们有一个性质:当 \(k\gt x\) 时 \(x^{\underline{k}}=0\)。也就是
也就是说,\(h_i=f(i)\) 是 \(f_i=\dfrac{1}{i!}\) 与 \(g_i=a_i\) 的卷积。
于是我们求出 \(h\cdot f^{-1}\) 即可。
FFT
板子,就不说了。
众所周知,多项式有两种表示,一种是最常用的系数表示,还有点值表示。点值表示的优点是可以非常快速地(\(\Theta(n)\) 地)做多项式乘法。
但是题目中给出的一般是多项式的系数表示,于是我们要将其转成点值表示。
两个次数为 \(n\) 的多项式乘起来之后次数为 \(2n\),所以需要选取 \(2n+1=\Theta(n)\) 个点。
如果随便选取 \(\Theta(n)\) 个点代入求值,那么是 \(\Theta(n^2)\) 的。还有优化的空间嘛?
以下设 \(n,N\) 均为偶数。
假设我们要选取 \(N\) 个点 \(x_1,x_2,\cdots,x_{N}\) 代入求值。注意我们可以随便选取这 \(N\) 个点。可不可以选择 \(\frac{N}{2}\) 个特殊的点使得我们只需要算出这 \(\frac{N}{2}\) 个点的值,我们就可以知道另外 \(\frac{N}{2}\) 个点的值?
聪明如你肯定想到了。相反数。
如果 \(f\) 是偶函数,那么 \(f(x)=f(-x)\)。
如果 \(f\) 是奇函数,那么 \(f(x)=-f(-x)\)。
但是多项式 \(f\) 可以是非奇非偶函数。但是我们可以将它的偶次项和奇次项提出来,得到两个新的函数。
注意到我们只需要算出左边和右边的两个函数 \(\frac{N}{2}\) 处的点值,就可以得到全部 \(N\) 个点值。
而我们设左边得到一个关于 \(\textcolor{red}{x^2}\) 的函数 \(g(x^2)\),右边为 \(h(x^2)\),我们可以得到
即
也就是说,我们只要保证 \(\{x_{i}\}\) 是由相反数两两配对而成的,也就是说,\(\{x_i\}=\{x_1,-x_1,x_2,-x_2,\cdots,x_{\frac{N}{2}},-x_{\frac{N}{2}}\}\),我们就能只计算其中的 \(\frac{N}{2}\) 个点值来得到这所有的 \(N\) 个点值。
递归之后我们得到了两个 \(\frac{n}{2}-1\) 次多项式。然后你会发现如果这样递归下去,最终是 \(T(n)=2T(\frac{n}{2})+\Theta(n)=\Theta(n\log n)\) 的。但是做完了吗?
如果仔细思考,就会发现一个致命的问题:我们要保证 \(\{x_{i}\}\) 是由相反数两两配对而成的。但是我们递归计算 \(g\) 的时候,我们要求的点值变成了 \(x_{1}^2,x_2^2,\cdots,x_{\frac{N}{2}}^2\),显然这不是两两配对的。那我们应该怎么办捏?
显然在 \(\mathbb{R}\) 内我们已经无法解决这个问题了。于是我们考虑在 \(\mathbb{C}\) 内解决这个问题。
\(\mathbb{C}\) 有个特别好的性质:它对开方是封闭的。亦即,\(\forall x\in \mathbb{C},\exists y\in \mathbb{C}\) 使得 \(y^2=x\)。证明从略。那么我们可以在 \(\mathbb{C}\) 内去求解(这是多么天才般的想法)!
我们举个例子吧。我们假设我们要求多项式 \(x^3+x^2-x-1\) 的 \(4\) 个点值。
我们不妨设起初(第 \(1\) 层)的四个点值为 \(\{x_1,-x_1,x_2,-x_2\}\)。
于是我们会把 \(x_1^2\) 和 \(x_2^2\) 分别代入去算。而我们希望在第 \(2\) 层中,这两个点也是正负对,即 \(x_1^2=-x_2^2\)。
最后我们需要把 \(x_1^4=x_2^4\) 代入去算第 \(3\) 层。我们不妨设 \(x_1^4=x_2^4=1\)。
那么 \(x_1^2=1, x_2^2=-1\) 是很自然的。
最后我们不难得到 \(x_1=1,x_2=\mathrm{i}\)。也就是说,我们只需要算 \(\{1,-1,\mathrm{i},-\mathrm{i}\}\) 处的点值即可。
\(\{1,-1,\mathrm{i},-\mathrm{i}\}\) 是四次单位根 \(\omega_4\)。具体地,如果要求 \(N\) 个点的点值,我们可以将其补成 \(2\) 的整次幂 \(N'\),然后计算 \(\omega_{N'}\) 处的点值即可。
对于 NTT,我们注意到若 \(N'\mid p-1\),则模数 \(p\) 的原根 \(g\) 具有和单位根同样良好的性质。于是直接套用即可。
分治 FFT
给定序列 \(g_{1\dots n - 1}\),求序列 \(f_{0\dots n - 1}\)。其中 \(f_i=\sum_{j=1}^if_{i-j}g_j\),边界为 \(f_0=1\)。
Solution 1
朴素地做是 \(\Theta(n^2)\) 的。观察到后面的项依赖前面的项。于是我们可以考虑用 cdq 分治实现。
具体地
-
若 \(l=r\),结束递归。
-
递归求解 \([l,mid]\)
-
计算 \([l,mid]\) 对 \([mid+1,r]\) 的影响。
-
求解 \([mid+1,r]\)。
\([l,mid]\) 对 \(f_i, i\in [mid+1,r]\) 的影响为 \(\sum _{j=l}^{mid} f_jg_{i-j}\)。
观察到这是一个卷积的形式。于是我们令 \(a_i=f_{l+i}\),\(b_i=g_i\),则计算出 \(c=a\ast b\),\([l,mid]\) 对 \([mid+1,r]\) 中 \(i\) 的贡献为 \(c_{i-l}\)。
时间复杂度 \(\Theta(n\log^2 n)\)。
Solution 2
令 \(F(x),g(x)\) 为 \(f,g\) 的生成函数。
则 \(F(x)G(x)=\sum_{i=0}^{+\infty} x^i\sum_{j+k=i}f_jg_k=F(x)-1\)。
故 \(F(x)=\frac{1}{1-G(x)}\)。
时间复杂度 \(\Theta(n\log n)\)。
任意模数多项式乘法(MTT)
Method 1:三模 NTT
由于 \(p\leq 10^9+9\),\(n,m\leq 10^5\),故最大的数可以到 \(p^2\cdot n=10^{23}\)(默认 \(n,m\) 同阶)级,故我们需要选取三个大素数使得 \(p_1p_2p_3\gt 10^{23}\)。
一般选取 \(p_1=469,762,049\),\(p_2=998,422,353\),\(p_3=1,004,535,809\),它们都存在原根 \(G=3\)。我们求出后可以利用 CRT 求出答案(需要利用 __int128)。
然而有一种不需要利用 __int128 的方法。
设
先合并前两个,那么
所以
故
于是我们求出了
不妨记 \(x_4=x_1+k_1A\)。那么
故 \(x\equiv x_4+k_4AB\pmod {ABC}\)。又由于 \(x\lt ABC\),故 \(x=x_4+k_4AB\)。
不过这个方法常数很大(需要做 \(9\) 次 NTT/INTT)。
Method 2:拆系数 FFT
我们设 \(c\) 是一个 \(\sqrt{p}\) 左右级别的整数。那么我们可以将 \(F(x)\) 拆成 \(A(x)+c\cdot B(x)\)。其中 \([x^i]A(x)=[x^i]F(x)\bmod c\),\(\displaystyle [x^i]B(x)=\lfloor\frac{[x^i]F(x)}{c}\rfloor\)。这样可以将系数降到 \(10^5\) 级别。
于是设 \(F(x)=A(x)+c\cdot B(x)\),\(G(x)=C(x)+c\cdot D(x)\),于是 \(F(x)G(x)=A(x)C(x)+c\left[A(x)D(x)+B(x)C(x)\right]+c^2\cdot B(x)D(x)\)。
设 \(T(x)=C(x)+D(x)\cdot \mathrm{i}\),其中 \(\mathrm i\) 为虚数单位。于是我们可以在 \(A(x)\cdot T(x)\) 中找到 \(A(x)C(x)\) 和 \(A(x)D(x)\),在 \(B(x)\cdot T(x)\) 中找到 \(B(x)C(x)\) 和 \(B(x)D(x)\)。
于是我们需要:
-
对 \(A(x)\),\(B(x)\),\(T(x)\) 做 DFT
-
对 \(A(x)T(x)\),\(B(x)T(x)\) 做 IDFT
共五次 FFT。常数是三模 NTT 的一半左右。但是这种方法无法通过精心构造的数据。
多项式乘法逆
考虑倍增。假设我们求出了 \(G_0(x)\) 使得 \(F(x)\cdot G_0(x)\equiv 1\pmod {x^n}\),我们考虑求出 \(G(x)\) 使得 \(F(x)\cdot G(x)\equiv 1\pmod {x^{2n}}\)。
由于 \(F(x)\cdot G(x)\equiv 1\pmod {x^{\textcolor{red}{2n}}}\),所以必有 \(F(x)\cdot G(x)\equiv 1\pmod {x^{\textcolor{red}{n}}}\)。于是我们有
则 \(F(x)\) 可消去,得到
考虑到 \(F(x)\cdot G(x)\equiv 1\),则两边同乘 \(F(x)\)
则 \(G(x)\equiv G_0(x)(2-F(x)G(x))\pmod {x^{2n}}\)。于是可以倍增求出。
我们有 \(T(n)=T(\frac{n}{2})+\Theta(n\log n)\),则时间复杂度为 \(\Theta(n\log n)\)。(但是你猜猜常数有多少?)
任意模数多项式乘法逆
把 NTT 换成任意模数的即可。
多项式除法
给定 \(f(x)\) 和 \(g(x)\),其中 \(n=\deg g\lt m=\deg f\)。求出 \(q(x), r(x)\) 满足 \(f=q\cdot g+r\),且 \(\deg q=\deg f-\deg g\),\(\deg r\lt \deg g\)。
好玄学的做法。
将 \(\frac{1}{x}\) 代入 \(f=q\cdot g+r\),得
即
定义 \(f^{R}\left(x\right)=x^{\deg f} f\left(\frac{1}{x}\right)\)。我们可以假装 \(r\) 是 \(m-1\) 次的。
则
于是我们在 \(\bmod x^{n-m+1}\) 意义下可以将 \(r\) 忽略掉。
那么在 \(\bmod x^{n-m+1}\) 意义下求一遍逆元,做一遍多项式乘法和减法即可。
多项式对数函数
对 \(G(x)\equiv \ln F(x) \pmod {x^n}\) 的两边求导,得
于是
时间复杂度 \(\Theta(n\log n)\)。
多项式 Newton 迭代
给定多项式 \(g(x)\),若已知 \(f(x)\) 满足 \(g(f(x))=0\),求出模 \(x^n\) 意义下的 \(f(x)\)。
考虑倍增。
边界是 \(n=1\),此时需要单独解出 \([x^0]g(f(x))=0\) 的解。
设已经得到了模 \(x^{\lceil\frac{x}{2}\rceil}\) 下的解 \(f_0(x)\)。
对 \(g(x)\) 在 \(f_0(x)\) 处进行 Taylor 展开,其中 \(g^{(i)}\) 表示对 \(g\) 求 \(i\) 阶导数,规定 \(g^{(0)}=g\)。
\(f(x)-f_0(x)\) 最低的非零项系数为 \(x^{\lceil\frac{n}{2}\rceil}\)。那么当 \(i\geq 2\) 时,\(2\lceil\frac{n}{2}\rceil\geq n\),在模 \(x^n\) 意义下为 \(0\),亦即,\(\forall i\geq 2\),都有 $ (f(x)-f_0(x))^i\equiv 0\pmod {x^n}$。
那么就很好做了。上式可以化简成
于是不难解得
那么我们不妨再来回顾一下多项式求逆。
给定 \(h(x)\),求出 \(f(x)\),使得 \(h(x)\cdot f(x)\equiv 1\pmod {x^n}\)。
观察牛顿迭代的形式
给定多项式 \(g(x)\),若已知 \(f(x)\) 满足 \(g(f(x))=0\),求出模 \(x^n\) 意义下的 \(f(x)\)。
我们要让左边是一个多项式,右边是 \(0\)。我们考虑变一下形。
即
那么令 \(g(f(x))=\frac{1}{f(x)}-h(x)\),我们得到
注意 \(g(f_0(x))\) 的主元是 \(f_0\)。不妨令 \(f_0=t\),则有 \(g(t)=\frac{1}{t}-h(x)\),这里 \(h(x)\) 当作常数,故 \(g'(t)=-\frac{1}{t^2}\)。
多项式 exp
给定 \(h(x)\),求出 \(f(x)\) 使得 \(\exp(h(x))\equiv f(x)\pmod {x^n}\)。
考虑变换形式。上式即
故 \(\ln f(x)-h(x)\equiv 0\pmod {x^n}\)。那么令 \(g(f(x))=\ln f(x)-h(x)\)。
应用 Newton 迭代的结论,我们得到
\(T(n)=T(\frac{n}{2})+\Theta(n\log n)\),所以时间复杂度为 \(\Theta(n\log n)\)。但是常数应该很大。
多项式开根
给定 \(h(x)\),求出 \(f(x)\) 使得 \(\sqrt{h(x)}\equiv f(x)\pmod {x^n}\)。
上式即 \(f^2(x)-h(x)\equiv 0\pmod {x^n}\)。于是令 \(g(f(x))=f^2(x)-h(x)\)。
\(T(n)=T(\frac{n}{2})+\Theta(n\log n)\),时间复杂度 \(\Theta(n\log n)\)。(可能需要求解二次剩余)
多项式快速幂
\(k\leq 10^{10^5}\)。
事实上,类似整数快速幂的实现可以做到 \(\Theta(n\log n\log k)\)。
普通版
普通版保证了 \(x_0=1\)。
加强版
首先我们设这个多项式的前 \(q\) 项系数为 \(0\),换句话说,\(\forall i\in [0,q-1]\),\([x^i]F(x)=0\)。
如果 \(q^k\geq n\),那么结果多项式为全 \(0\)。
否则设 \(y=[x^q]F(x)\)。我们先给整个多项式乘上 \(y^{-1}\),最后还原的时候再乘上 \(y^{k}\)。
我们把 \(a_q,a_{q+1},\cdots,a_{n-1}\) 平移到 \(a_0,a_1,\cdots,a_{n-q-1}\)。然后对这个新多项式用套用普通版的方法进行快速幂。
最后乘上 \(y^{k}\),在新多项式前面补上 \(kq\) 个 \(0\) 即可。
注意,计算 \(y^k\) 时的 \(k\) 是对 \((p-1)\) 取模的。而计算 \(\ln\) 时的 \(k\) 是对 \(p\) 取模的。
P2767 树的数量
求出包含 \(n\) 个节点(无标号)的有根 \(m\) 叉树的个数,对 \(10,007\) 取模。
两个有根树相同,当且仅当其根节点相同,且从左到右每一棵子树也相同。特别地,两个有根树均为空树,视为两个有根树相同。
\(n,m\le 127\)。
套路地设 \(f[n]\) 为有 \(n\) 个节点的有根 \(m\) 叉树的数量。显然 \(f[0]=1\)。
则
那么
CF438E The Child and Binary Tree
对于 \(\forall i\in[1,m]\),求出权值为 \(i\) 的二叉树的数量,对 \(998,244,353\) 取模。
定义二叉树的权值为节点的权值之和。给定大小为 \(n\) 的正整数集 \(C\),节点的权值可以从 \(C\) 中选取。
两棵二叉树不同当且仅当:
- 它们的节点数量不同;
- 或树的形态不同;
- 或存在一个点的点权不同。
\(n,m\le 10^5\)。
套路地设 \(f_i\) 为权值为 \(i\) 的二叉树的数量。显然地,有
特别地,\(f_0=1\)。
不妨设 \(G=\sum g_ix^i\),\(F=\sum f_ix^i\),其中 \(g_i=[i\in C]\)。那么其实就是
那么
也就是说
解得
讨论正确性。
- 取 \(+\) 号的时候,\(G\to 0\) 时 \(F\to \infty\);
- 取 \(-\) 号的时候,\(G\to 0\) 时 \(F\to 1\)。
因此取 \(-\)。那么就是
然后你发现 \(G\) 的零次项一定是 \(0\),无法求逆。
但是我们上下同时乘以 \(1+\sqrt{1-4G}\),得到
然后多项式求逆+开根即可。时间复杂度 \(\Theta(m\log^2 m)\)。
P4389 付公主的背包
求
要求求出 \(x^1,x^2,\cdots,x^m\) 的系数。
\(n,m\leq 10^5\)。
不难想到取 \(\ln\),于是化为求
我们有 \(\ln(1-x)\) 的 Taylor 级数:
代入就可以得到
于是问题转化为
需要注意的是,不能对于每一个 \(v_i\) 朴素地直接求和,会被 \(n\) 个 \(1\) 卡掉。
正确的做法是,求出 \(i\) 在数列 \(v\) 出现的次数 \(cnt_i\),然后求
最后别忘了 \(\exp\) 回来。
将 \(n,m\) 视为同阶,时间复杂度 \(\Theta(n\log n)\)。
P7431 [THUPC2017] 小 L 的计算题
给定非负整数数组 \(a\),长度为 \(n\)。定义
对于 \(i\in [1,n]\),求出 \(f_i\)。
\(n\le 4\times 10^5\)。
写出 OGF。设 \(F(x)=\sum_{i\ge 0} f_ix^i\)。
推到这一步,已经可以利用分治 NTT 维护分子和分母,做到 \(\Theta(n\log^2 n)\),不过常数是巨大的(反正我的 vector V5 板子 T 了 qaq)。当然,我们有更好的做法。

浙公网安备 33010602011771号