子集卷积 / 求逆
这个不用多说了。把一维变为两维,分别做 OR 卷积和普通的卷积。O(2nn2)。
求逆就是乘法的逆运算。做正常的 O(n2) 多项式暴力求逆即可。
exp / ln
我们使用类似子集卷积的技巧,集合幂级数 exp 就变成了要求出下面的这么一个 g:
fk,S=∣T1∣+∣T2∣+⋯+∣Tk∣=∣S∣,T1∪T2∪⋯∪Tk=S∑i=1∏kaTigS=k=0∑∣S∣k!fk,S
并起来恰好等于的限制不好处理,我们做个高维前缀和,使得每个 Tk 之间相互独立,这样就可以转化成多项式 exp 了;最后再差分回去。
f′k,S=Ti⊆S,∣T1∣+∣T2∣+⋯+∣Tk∣=∣S∣∑i=1∏kaTiF′S(x)=T⊆S∑aTx∣T∣G′S(x)=k=0∑∣S∣k!F′Sk=exp(F′S)
求出所有的 F′S 可以 O(2nn2) 完成,那么对于每一个 S 都暴力 O(n2) exp 即可求出 G′。最后差分回去即可得到 G,有 gs=[x∣S∣]GS(x)。
ln 是 exp 的逆运算,考虑反过来依次撤销 exp 的三个操作,就是做高维前缀和,做多项式 ln,再差分回去。
总结下来就是,集合幂级数 卷积 / 求逆 / exp / ln 的流程就是,先做高维前缀和,再分别做多项式 卷积 / 求逆 / exp / ln,再差分回去。
逐点牛顿迭代
考虑集合幂级数 exp 的组合意义,把 [n] 无序的划分为若干个集合,每个集合的权值乘积之和。直接考虑一个 dp:fi,j,S 表示已经考虑了前 i 个元素,划分了 S 内的元素,还需要划分出 j 个集合的方案数。转移是显然的:
fi−1,j,S→fi,j,S (i∈S)fi−1,j,S×gT→fi,j−1,S∪T (maxT=i,S∩T=∅)
可以用子集卷积优化。
分析一下时间复杂度,对于一个 i 我们要做 n−i 次大小为 2i 的子集卷积,是 ∑i=0n(n−i)2ii2。显然有 ∑i=0n(n−i)2i<2n+1,于是时间复杂度还是 O(2nn2) 的。
发现这个东西非常的厉害。如果要求的东西是 ∑i≥0aiFi,那么直接把 dp 初值 f0,i,∅ 设为 aii! 即可。
那么 exp 就是 ai=i!1,ln 就是 ai=i(−1)i−1,k-exp 就是 ai=[i≤k]i!1,求幂次就是 ai=[i=k],至于求逆可以先求 1−F(x)1 再变回来,ai=1。而且这些东西都不需要使用逆元。但是注意求逆需要保证 F(∅)=1。
如果可以使用逆元,但是不保证 F(∅)=1 可以求出 F(∅)1 乘一下。