多项式
拉格朗日插值
\(f(x)=\sum\limits_{i=1}^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}\)。不过一般题目都是求值的。
连续取值插值
当题目给出的点为连续整数的时候我们可以线性处理,方法就是维护先后缀乘积。
最后得出 \(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}\) 即可。
FFT/NTT
卷积为形如 $$F(i)=\sum\limits_{j=0}^if_j*g_{i-j}$$
快速求出所有 \(F(i)\) 满足 \(i∈[0,t]~(n \ge t\) 且 \(m \ge t)\)时,考虑
进行 FFT/NTT,可得\(F(i)=h_i\),\(h_i\) 为 \(x^i\)的系数。更高位 \((i \ge t+1)\) 舍去即可。
乘积式下标差一定,考虑翻转构造卷积。
\(\sum f(i)*g(i+j)\) 可以 \(reverse(g_i)\),转化为 \(\sum f(i)*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\)。
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\),那么
又 \(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
令 \(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
令 \(G(x)=e^{F(x)}\),
暴力做法:\(g_i=\dfrac{1}{i}\sum\limits_{j=1}^ijf_jg_{i-j}\),\(g_0=1\)。