专栏文章

Bostan-Mori 算法

算法·理论参与者 11已保存评论 10

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
10 条
当前快照
2 份
快照标识符
@mk8jxjht
此快照首次捕获于
2026/01/11 01:01
上个月
此快照最后确认于
2026/02/19 01:20
11 小时前
查看原文
Bostan-Mori 用于提取有理分式的远端系数 [xn]P(x)Q(x)[x^n]\dfrac{P(x)}{Q(x)},其中 nn 很大,max(degP,degQ)\max(\deg P,\deg Q) 是常见的 m=105m=10^5 范围。
分子分母同时乘上 Q(x)Q(-x) 后,发现分母 Q(x)Q(x)Q(x)Q(-x) 仅余偶次项,不妨令其为 G(x2)G(x^2);将分子 P(x)Q(x)P(x)Q(-x) 拆为 F0(x2)+xF1(x2)F_0(x^2)+xF_1(x^2),原式化为 F0(x2)G(x2)+xF1(x2)G(x2)\dfrac{F_0(x^2)}{G(x^2)}+x\dfrac{F_1(x^2)}{G(x^2)},分 nn 的奇偶到其中一侧递归求解即可,时间复杂度为 O(mlogmlogn)\mathcal O(m\log m\log n)

提取 [xn]lnF(x)[x^n]\ln F(x)[xn]lnF(x)=[xn]F(x)F(x)dx=1n[xn1]F(x)F(x)[x^n]\ln F(x)=[x^n]\displaystyle\int\dfrac{F'(x)}{F(x)}\text{d}x=\dfrac 1n[x^{n-1}]\dfrac{F'(x)}{F(x)}
提取 [xn]i=1mPi(x)Qi(x)[x^n]\displaystyle\sum_{i=1}^m\dfrac{P_i(x)}{Q_i(x)}[xn]i=1mPi(x)Qi(x)=[xn]i=1mPi(x)jiQj(x)i=1mQi(x)[x^n]\displaystyle\sum_{i=1}^m\dfrac{P_i(x)}{Q_i(x)}=[x^n]\dfrac{\sum_{i=1}^mP_i(x)\prod_{j\neq i}Q_j(x)}{\prod_{i=1}^mQ_i(x)},分子分母都可以分治乘求出。
顺便提一嘴 (i=1nFi(x))=i=1nFi(x)jiFj(x)\left(\displaystyle\prod_{i=1}^nF_i(x)\right)'=\displaystyle\sum_{i=1}^nF_i'(x)\displaystyle\prod_{j\neq i}F_j(x),有时候(比如说求 1x+ai\dfrac{1}{x+a_i} 之和的时候)能够少一个分治乘。
举个若智的例子,比如说求 i=1naik\displaystyle\sum_{i=1}^na_i^kkk 很大,就是求 [xk]i=1n11aix[x^k]\displaystyle\sum_{i=1}^n\dfrac{1}{1-a_ix},用上面的方法就能做到 O(nlognlogk)\mathcal O(n\log n\log k)
这玩意的主要用途貌似还是常系数齐次线性递推。

和常系数齐次线性递推:首先提取有理分式的远端系数问题可以转为常系数齐次线性递推,设 Q(x)F(x)=P(x)Q(x)F(x)=P(x),有 i=0n[xi]Q(x)[xni]F(x)=[xn]P(x)\displaystyle\sum_{i=0}^n[x^i]Q(x)[x^{n-i}]F(x)=[x^n]P(x),即:
[xn]F(x)=1[x0]Q(x)([xn]P(x)i=1n[xi]Q(x)[xni]F(x))[x^n]F(x)=\dfrac{1}{[x^0]Q(x)}\left([x^n]P(x)-\sum_{i=1}^n[x^i]Q(x)[x^{n-i}]F(x)\right)
n>mn>m[xn]P(x)=[xn]Q(x)=0[x^n]P(x)=[x^n]Q(x)=0,此时就变成常系数齐次线性递推。
常系数齐次线性递推也可以转为上述问题:设有递推关系 fn=i=1maifnif_n=\displaystyle\sum_{i=1}^ma_if_{n-i} 及初值 f0,f1, ⁣,fm1f_0,f_1,\cdots\!,f_{m-1},设 ff 的 OGF 为 F(x)F(x)A(x)=i=1maixiA(x)=\displaystyle\sum_{i=1}^ma_ix^iF0(x)=i=0m1fixiF_0(x)=\displaystyle\sum_{i=0}^{m-1}f_ix^i,不难验证有:
F(x)=A(x)F(x)+F0(x)(A(x)F0(x)modxm)F(x)=A(x)F(x)+F_0(x)-(A(x)F_0(x)\bmod x^m)
因此有:
F(x)=F0(x)(A(x)F0(x)modxm)1A(x)F(x)=\dfrac{F_0(x)-(A(x)F_0(x)\bmod x^m)}{1-A(x)}
使用 Bostan-Mori 即可做到 O(mlogmlogn)\mathcal O(m\log m\log n) 求解单项,常数很小。
原来这个东西叫做 LSB-first 吗。

多次询问:直接做是 O(qmlogmlogn)\mathcal O(qm\log m\log n) 的,考虑转成常系数齐次线性递推之后用多项式取模做法,预处理块幂,这样是 O(Bm+nmlogmB+qmlogm)\mathcal O\left(Bm+\dfrac{nm\log m}{B}+qm\log m\right) 的,取 B=O(nlogm)B=\mathcal O(\sqrt{n\log m}) 有最优复杂度 O(mnlogm+qmlogm)\mathcal O(m\sqrt{n\log m}+qm\log m),或者说预处理多层块幂可以达到更好的平衡?比方说有 D+1D+1 层,底层分块块长为 BB,其它就按照 (nB)1/D\left(\dfrac nB\right)^{1/D} 分,这样复杂度是 O(Bm+D(nB)1/Dmlogm+qDmlogm)\mathcal O\left(Bm+D\left(\dfrac nB\right)^{1/D}m\log m+qDm\log m\right),取 B=O(DD/(D+1)n1/(D+1)logD/(D+1)m)B=\mathcal O(D^{D/(D+1)}n^{1/(D+1)}\log^{D/(D+1)}m) 有最优复杂度 O(mDD/(D+1)n1/(D+1)logD/(D+1)m+qDmlogm)\mathcal O(mD^{D/(D+1)}n^{1/(D+1)}\log^{D/(D+1)}m+qDm\log m),魔怔。
好吧 Bostan-Mori 本身也是可以多叉的?设 T=2tT=2^t,那么 i=0T1Q(ωTix)\displaystyle\prod_{i=0}^{T-1}Q(\omega_T^ix) 只有次数是 TT 的倍数的项系数非零,计算 P(x)i=1T1Q(ωTix)i=0T1Q(ωTix)\dfrac{P(x)\prod_{i=1}^{T-1}Q(\omega_T^ix)}{\prod_{i=0}^{T-1}Q(\omega_T^ix)} 的复杂度是 O(mTlogm)\mathcal O(mT\log m) 的,这样分割一次后直接跑多项式乘法逆,复杂度为 O(mTlogm+qnlogmT)\mathcal O\left(mT\log m+\dfrac{qn\log m}{T}\right),平衡一下复杂度是 O(nmqlogm)\mathcal O(\sqrt{nmq}\log m) 的。
不过如果只算分母的话,每次从 2t12^{t-1} 倍增合并到 2t2^t,复杂度是 O(ntlogm)\mathcal O(nt\log m) 的,但是分子还是算不了。

Bostan-Mori 还可以拓展到高维情况,只需要需提取的项 [x0nx1k1x2k2xdkd][x_0^nx_1^{k_1}x_2^{k_2}\cdots x_d^{k_d}]k1,k2, ⁣,kdk_1,k_2,\cdots\!,k_d 较小即可,复杂度大概是 O(m(ki)logn(logm+logki))\mathcal O(m(\prod k_i)\log n(\log m+\sum\log k_i))
还能够做一些位运算有关的魔怔东西,比方说求 nn[xn]P(x)Q(x)\displaystyle\sum_{n'\subseteq n}[x^{n'}]\dfrac{P(x)}{Q(x)},只需要 F1(x)+F0(x)F_1(x)\stackrel{+}{\gets}F_0(x) 即可。

可是 [xn]expF(x)[x^n]\exp{F(x)}[xn]F(x)[x^n]\sqrt{F(x)} 都只能整式递推/dk/dk

评论

10 条评论,欢迎与作者交流。

正在加载评论...