版权声明:随意转载哦......但还是请注明出处吧: https://blog.csdn.net/dreaming__ldx/article/details/85372365
多项式乘法
这个大家应该都会吧
还是推一推吧。
已知的:
A(x)=∑i=0naixi
B(x)=∑i=0mbixi
要求的:
C(x)=A(x)B(x)=∑i=0n+m(∑j=0min{i,n}aj∗bi−j)xi
显然直接暴力做是
O(n2)的,考虑如何优化。
那么我们使用
fft或者
ntt来实现点值表示法和系数表示法之间的快速转化。
为了方便起见,我们将
A,B的最高次数统一成一个
2的幂(对于超过
n/m的项次数看成0即可)
所谓的系数表示法就是我们平常用的那种。
而点值表示法,就是把这个多项式理解成一个函数,用这个函数上的若干个点的坐标来描述这个多项式:
f(x)=(x0,y0),(x1,y1),...,(xn,yn)=p0,p1,p2,...,pn
假设我们已经将
A,B两个函数转化成了点值表示,于是就可以马上求出
C的点值表示:
A(x)=(xa,0,ya,0),(xa,1,ya,1),...,(xa,n−1,ya,n−1)=pa,0,pa,1,...,pa,n−1
B(x)=(xb,0,yb,0),(xb,1,yb,1),...,(xb,n−1,yb,n−1)=pb,0,pb,1,...,pb,n−1
那么
C(x)=pa,0∗pb,0,pa,1∗pb,1,...,pa,n−1∗pb,n−1=pc,0,pc,1,...,pc,n−1
然后再把
C(x)还原成系数表达式即可。
注意:我们需要保证
xai,xbi互不相同)
现在就只用考虑如何实现点值表示和系数表示的互换了。
也就是如何用更少的计算次数来求出
n个不同的
x值对应的
y值。
考虑有两个具有特殊性质的东西:
- 单位根
- 原根
单位根保证了
wn0,wn1,...,wnn−1是互不相同的并且有
wnij=(wni)j
而原根在模数为质数
p的时候也有
g0,g1,g2,...,gn−1是互不相同的并且
gij≡(gi)jmodp
这满足了我们上面的性质,因此我们考虑将
wn0,wn1,...wnn−1作为
x0,x1,...xn−1带入求点值。
然后要用到两个引理:
- 折半引理:
wnk∗2=w2nk(n为偶数 )
- 消去引理:
wnk=−wnk+2n
这两个引理可以画个单位圆简单证明(建议各位神犇自己简要证明一下)
然后利用按照下标的奇偶性来进行分治处理:
f(x)=∑i=0naixi
=>
f(wnk)=∑i=0naiwnik
=>
f(wnk)=∑i=02n−1a2iwn2ik+wnk∑i=02n−1a2i+1wn2ik
同时又有:
f(wnk+2n)=∑i=02n−1a2iwn2ik−wnk∑i=02n−1a2i+1wn2ik
这一步需要用到引理
所以我们只要算出两个重新分配了系数的多项式的值就可以了。
显然一直分下去只有
log层。
于是总时间复杂度
O(nlogn)
注意到递归的时间复杂度很慢,我们可以预处理最后一层的系数的位置然后用迭代的方式还原回去来优化常数
这就成功的实现了系数转点值。
下面来看点值转系数:
以上是
fft的证明,
ntt同理。
一道板题:uoj#34多项式乘法
fft写法
ntt写法
fft,ntt做多项式乘法相关题目
cc PRIMEDST 点分治+
fft优化合并
bzoj4259
fft套路题
spoj Triple Sums
fft+容斥原理
bzoj4827 推式子练习
hdu5829 推式子练习