分治NTT

分治NTT

前置知识

多项式定义,运算以及所有相关算法。

例题1

现有一转移式形如 \(f(i)=\sum _{j=0} ^{i} f(j)g(i-j)\),其中终止条件 \(f(0)=1\)。由于 \(f(j)g(i-j)\) 是卷积的形式,不难想到NTT。但是前面的 \(f(j)\) 会对后面的 \(f(i)\) 做贡献,所以不能直接NTT。

这种前面的操作只会对后面的查询产生贡献的问题,不难想到CDQ分治这个算法。所以我们考虑分治NTT。

具体来说,我们需要将问题分为三部分:递归解决左半的问题,计算左半对右半的贡献,递归解决右半的问题。

考虑左半对右半的贡献是什么。设我们当前解决的问题是 \(l\)\(r\) 区间的,定义 \(mid=\frac {l+r}{2}\)。那么左半对右半的贡献 \(f(i)=\sum _{j=l}^{mid} f(j)g(i-j)\)\(f(j)g(i-j)\) 是一个卷积的形式,所以可以直接把 \(f\)\(l\)\(mid\)\(g\)\(0\)\(r-l\) 提出来,对这一部分进行NTT。

时间复杂度为 \(O(n\log^2_{}{n})\)。证明与CDQ分治的时间复杂度类似。

例题2

现需要求一多项式 \(F(x)=\prod _{i=1} ^m (x^{a_i}+1)\)。其中 \(\sum a_i=n\)。如果我们从左往右依次卷积,最坏时间复杂度为 \(O(n^2\log n)\)。究其根本是因为我们做卷积的多项式长度之和为 \(\sum a_i(m-i+1)\) 也就是 \(n^2\) 级别的。

考虑分治,先将编号为 \(l\)\(mid\)\(mid+1\)\(r\) 的分别递归卷积,然后将两部分卷积起来。递归树的深度是 \(\log n\) 级别的,这也就意味着每个式子只会被计算 \(\log n\) 次,总时间复杂度就变成了 \(O(n\log^2 n)\)

例题3

现在需要求出 \(\sum _{i=1} ^n \frac{1}{1-a_ix}\)。直接多项式求逆再加是肯定不行的。考虑如下两种方法。

法1

考虑现有多项式 \(A\)\(B\)\(C\)\(D\)。则 \(\frac{A}{B} + \frac{C}{D}=\frac{AD+BC}{BD}\)。所以可以直接卷积求出 \(AD\)\(BC\)\(BD\)。时间复杂度 \(O(n^2\log n)\) ,用上面例题2的方法分治NTT求解可以使时间复杂度降为 \(O(n \log^2 n)\)

法2

考虑 \([\ln(1-a_ix)]'=\frac{-a_i}{1-a_ix}\),等式两边同时乘上 \(x\) 得到 \(x[\ln(1-a_ix)]'=\frac{-a_ix}{1-a_ix}=1-\frac{1}{1-a_ix}\) 。则 \(\sum _{i=1}^{n} x[\ln(1-a_ix)]'=n-\sum _{i=1}^n \frac{1}{1-a_ix}\)。所以我们只需要把左边的式子求出来就好了。

因为 \([f(x)+g(x)]'=f'(x)+g'(x)\) 所以左边的式子就是 \(x [\sum _{i=1}^n \ln(1-a_ix)]'\) 则为 \(x \{\ln[\prod _{i=1}^n(1-a_ix)] \}'\) 。直接用例题2的分治NTT求解 \(\prod _{i=1}^n (1-a_ix)\) 然后多项式 \(\ln\),多项式求导即可。时间复杂度 \(O(n \log^2n)\)

posted @ 2023-02-25 15:03  slenbol  阅读(743)  评论(0)    收藏  举报