多项式

拉格朗日插值

一个 \(n\) 次多项式,需要 \(n+1\) 个点来确定。

\[f(x)=\sum\limits_{i=0}^n y_i\prod\limits_{i \neq j}\frac{x-x_j}{x_i-x_j} \]

如果求系数可以 \(O(n^2)\) 预处理 \(g(x)=\prod (x-x_i)\)。然后对于每个 \(i\),有 \(f_i(x)=\frac{g(x)}{x-x_i} \times \frac{y_i}{\prod\limits_{i \neq j}x_i-x_j}\)

不过一般题目都是求值的,直接把 \(x\) 的具体值代入即可。

连续取值插值

当题目给出的点为连续整数的时候我们可以线性处理,方法就是维护先后缀乘积。

最后得出 \(f(k)=\sum\limits_{i=1}^ny_i\frac{pre_{i-1}suf_{i+1}}{fac_{i-1}fac_{n-i}}\),需要注意的是如果 \(n-i\) 为奇数的时候,分母要加负号。

重心插值法

可以动态加点。

变形一下得到 $f(x)=\prod(x-x_i) \sum \frac{y_i}{\prod\limits_{i \neq j} (x-x_i)(x_i-x_j)} $。

只需要动态维护 \(h_i=\frac{y_i}{\prod\limits_{i\neq j} x_i-x_j}\) 即可。

例题

注意,在进行插值的时候,比如是关于 \(c\) 的多项式,那么前面预处理的时候所有和 \(c\) 有关的项都要放进去,不能说有些东西是统一的就放在最后乘,这会影响多项式的。

一般用于优化 DP,在通信题也可以用来压缩信息。

优化 DP 情景总结:

  • 二维平面图行走

  • 发现某个值非常大,而且其贡献是一个多项式,比如多次乘上一个一次函数贡献,或者组合数贡献有的时候也是多项式。

XYD10163.奖励

dp 的第二维是一个多项式,证明直接放个图吧。

于是对于 \(r-l\le 10^5\) 的部分分,可以直接 \(O(n^3)\) 暴力 dp,找到最后一列的 \(O(n)\) 个点,拉格朗日插值即可,然后对于连续若干个点求值。

对于 \(l,r\) 更大的情况,由于一个多项式的和依然为一个多项式。

所以我们对于这个多项式的前缀和进行插值。这个多项式的次数应该是原来的次数 \(+1\),也就是 \(2n-1\) 次,所以我们需要 \(2n\) 个点。这题可以发现上面的 dp 值会影响下方的 dp 值,所以我们肯定是需要取到最上面的 \([h-n+1,h+n]\) 进行插值,但是 dp 的部分需要取到 \([h-2n,h+n]\),因为可以一下子往下掉落很多,所有更底下部分也会影响 \(f(h-n)\)

P10832 [COTS 2023] 传 Mapa

考虑将题目给的 key 和 value 看出函数上的 \(n\) 个点 \((x_i,y_i)\),使用拉格朗日插值转化为 \(n\) 个系数,这样子就将信息量由 \(2n\) 压缩到了 \(n\),可是通过拉格朗日插值我们不方便求出系数,只能求点值。于是我们传输 \(x\in [1,n]\) 的点值过去,再利用这些点值再做一次拉插来回答询问。

P5223 Function

由递推式可以知道 \(f_{i,j}\) 是关于 \(i\)\(j-1\) 次多项式。

由于单点是多项式,所以行内前缀和也是多项式。暴力算出 \((2k,2k)\) 以内的所有值,对于行内前缀和得到的若干个点进入拉格朗日插值,并带入 \(n\) 就可以得到答案了。

P11420 [清华集训 2024] 乘积的期望

题解太长,放在洛谷了

本题中关于拉格朗日插值相关的要点:

从本题的暴力 DP 中可以看出,可以发现 DP 部分和 \(C\) 无关,只是针对与 DP 的下标最后乘以了和 \(C\) 相关的组合数,可以发现这是一个多项式的贡献,于是可以 DP 出 C 很小的情况,然后进行插值求出 \(C\) 大情况下的答案。

P12251 [科大国创杯初中组 2025] 抽卡

FFT/NTT

多项式乘法,即快速计算 \(h(x)=f(x)\times g(x)\),直接系数暴力乘是 \(O(n^2)\) 的。

但是可以通过如下手段:系数 \(\xrightarrow{DFT}\) 点值(进行点乘) \(\xrightarrow{IDFT}\) 系数,做到 \(O(n\log n)\)

具体来说,由于点值是可以直接对应位置相乘的,所以如果我们能对于 \(f(x)\)\(g(x)\) 分别求出 \(n\) 个点值,只需要直接 \(O(n)\) 乘就可以得到 \(h(x)\)\(n\) 个点值,再复原就能得到 \(h(x)\) 的系数。

所以重点在于如何进行 DFT 和 IDFT。我们需要巧妙构造一些横坐标来加速运算。

首先需要将 \(f\) 数组长度补齐至 \(2\) 的次幂(这方便我们递归运算),设为 \(n\)。这里采用 \(n\) 次单位根来算。

我们要求出 \(f(w_n^0),f(w_n^1) \dots f(w_n^{n-1})\)。考虑递归计算,将 \(f(x)\) 按照 \(x\) 次幂的奇偶性分解为两个 \(x^i\to x^{\lfloor\frac{i}{2}\rfloor}\) 的多项式,\(f(x)=f_o(x^2)+xf_e(x^2)\)

\[f(w_n^k)=f_e(w^{2k}_n)+w_n^kf_o(w_n^{2k}) \]

\[f(w_n^{k+\frac{n}{2}})=f_e(w^{2k+n}_n)+w_n^{k+\frac{n}{2}}f_o(w_n^{2k+n}) \]

根据复数的性质进行化简可得,

\[f(w_n^k)=f_e(w^k_{\frac{n}{2}})+w_n^kf_o(w^k_{\frac{n}{2}}) \]

\[f(w_n^{k+\frac{n}{2}})=f_e(w^{k}_{\frac{n}{2}})-w_n^kf_o(w_{\frac{n}{2}}^k) \]

运用这条性质可以递归到计算两个 \(\dfrac{n}{2}\) 次多项式的 \(\dfrac{n}{2}\) 次单位根的点值,规模变为了原来的一半,所以时间复杂度是 \(O(n\log n)\)。这样子就完成了 DFT 的过程。

IDFT 就是

卷积

卷积为形如 $$F(i)=\sum\limits_{j=0}^if_j\times g_{i-j}$$
快速求出所有 \(F(i)\) 满足 \(i∈[0,t]~(n \ge t\)\(m \ge t)\)时,考虑

\[h(x)=f(x)\times g(x)=\sum\limits_{i=0}^{n+m}\sum\limits_{j=0}^if_jg_{i-j}\times x^i \]

进行 FFT/NTT,可得\(F(i)=h_i\)\(h_i\)\(x^i\)的系数。更高位 \((i \ge t+1)\) 舍去即可。

乘积式下标差一定,考虑翻转构造卷积。

\(\sum f(i)\times g(i+j)\) 可以 \(\mathrm{reverse} (g_i)\),转化为 \(\sum f(i)\times g(n-i-j+1)\)

BZOJ4503. 两个串

字符串匹配题可以考虑卷积,通位符的那一位设置为 \(0\) 即可。\(s(j+1)\) 满足条件当且仅当\(\sum\limits_{i=1}^m(s_{i+j}-T_i)^2T_i=0\)。这显然可以翻转构造卷积。下面有些细节要处理。
\(F(j)=\sum\limits_{i=1}^mS_2(i+j)*T(i)\) 发现 \(i\) 的上限 \(m\)\(j\) 无关,所以需要在 \(T\) 数组后面添加0,使得 \(T\)\(S\) 长度相等,故 \([1,m] \to [1,n-j]\) 并且 \([j+1,j+m] \to [j+1,n]\)。然后注意只有翻转 \(S\) 才能使得二者下标之和为 \(n-j+1\),与上限 \(n-j\) 不符合怎么办,令 $ (n-j) \to (n-j+1)$ ,因为 \(T~S\) 增加的那两位均为 \(0\),不影响结果。得到\(F(i)=\sum\limits_{j=1}^{m-i+1}S_2(m-i-j+1)*T(j)\) 上限不是 \(i\) 怎么办 \(swap(i,m-i+1)\) 即可。
以上做法麻烦了,但是有点启发性,我也懒得修改了,其实直接翻转 \(S\) 在其前面加0,直接推导就出来了。
需要注意的补 \(0\) 不需要真正在数组中加 \(0\)

一堆加法为不同定值,可以卷积

BZOJ3513. [MUTC2013]idiots

我们可以先算出不能组成三角形的概率,那么就是枚举最长边然后算另外两边小于等于该数的概率(注意如果直接算大于它的概率的话会把自己算进去导致重复选择同一木棒)。这个可以通过计算 \(s(n)\) 表示选两边和为 \(n\) 的方案数,这个可以通过 FFT 解决,最后前缀和即可。

积化和,使用卷积

P3321 [SDOI2015] 序列统计

如果是选两个数和为某一值就是上一题,如果是选 \(k\) 个数的话可以考虑用二进制拆分加速。\(h_t\) 表示选择了 \(2^t\) 个数,先预处理以下,然后拆分 \(k\)

\[h_t=\sum\limits_{i=1}^nh_{t-1}(i) \times h_{t-1}(n-i) \]

ans[0]=1;//初始化 for(int i=30;~i;i--){ if((k>>i)&1){ FFT(ans,h[i]); } }
如果带取模呢,每次 FFT 之后 \(ans(n~mod~i) \gets~ans(n)\)
到了本题首先可以积化和,这个指对函数可以实现。考虑 \(a^{s/t/z}~ mod~m=x/y/k\),那么

\[x \times y=k \Leftrightarrow a^s \times a^t \equiv a^z~(mod~m) \]

\(a^s \times a^z =a^{s+t}\),所以可以得到等式成立的充分条件为 \(\textcolor{blue}{s+t \equiv z~(mod~m-1)}\)
注意到上述推导成立的必要条件为 \(a^i~mod~m\) 互不相同。这样才能完成每一个映射,且蓝笔部分推广到充要。这恰好是原根的定义,于是这里取 \(a\)\(m\) 的一个原根即可。

各类操作

多项式求逆

分治NTT

\(f_i=\sum\limits_{j=1}^i f_{i-j}\times g_j\)

我们发现 \(f_i\) 的求解依赖于 \(f_0-f_{i-1}\),于是我们考虑分治求解。
设当前 \(\operatorname{solve}(l,r)\),说明已经考虑完了 \(f_0-f_{l-1}\)\([l,r]\) 的贡献。我们先处理 \((l,mid)\) 之后算出了 \(f_l-f_{mid}\) 的值,我们再用这些值来贡献 \([mid+1,r]\)\(f_i\gets\sum\limits_{j=l}^{mid}f_j\times g_{i-j}\),令 \(f'_i=f_{i-l}\)\(h=f'\times g\),于是 \(f_i\gets h_{i-l}\)

多项式 ln

掌握 \(O(n\log n)\) 的做法没啥必要吧,会 \(O(n^2)\) 暴力卷积就行了。

\(G(x)=\ln(1+F(x))\)
暴力做法:\(g_i=f_i-\dfrac{1}{i}\sum\limits_{j=1}^{i-1}jg_jf_{i-j}\)\(g_0=0\)

多项式 exp

掌握 \(O(n\log n)\) 的做法没啥必要吧,会 \(O(n^2)\) 暴力卷积就行了。

\(G(x)=e^{F(x)}\)
暴力做法:\(g_i=\dfrac{1}{i}\sum\limits_{j=1}^ijf_jg_{i-j}\)\(g_0=1\)

posted @ 2024-01-07 00:00  Mirasycle  阅读(39)  评论(0)    收藏  举报