多项式运算
本文所讲所有的多项式运算全部基于vector的使用
1 | typedef vector<int> Poly; |
0.思想
自认为多项式最重要的思想就是倍增了
其次就是分治
建议先看看fft残疾人手册
和ntt残疾人手册
1.多项式加法
$C(n)=A(n)+B(n)$
就是系数相加,非常简单的实现
1 | Poly add(Poly a, Poly b) { |
2.多项式减法
$C(n)=A(n)-B(n)$
系数相减,依旧简单的实现
1 | Poly sub(Poly a, Poly b) { |
3.多项式乘法
$C(n)=\sum_{i=0}^nA(i)B(n-i)$
就是ntt
需要预处理原根的次幂
交换位置的时候动态处理就好,因为在倍增过程中ntt的长度不一样
1 | int w[2][N]; |
4.多项式求逆
对于多项式$A$,我们要求出$B$
满足$A\ast B=1(\mod x^{n+1})$
这里的$\mod x^n$是保留前$n+1$个系数的意思,不然$B(n)$会有无穷项
我们假设已经求出了$B’$满足$A\ast B’=1(\mod x^{\lceil\frac{n}{2}\rceil})$
那么因为存在$A\ast B=1(\mod x^{\lceil\frac{n}{2}\rceil})$
所以$A\ast (B-B’)=0(\mod x^{\lceil\frac{n}{2}\rceil})$
又因为A不是0,所以$(B-B’)=0(\mod x^{\lceil\frac{n}{2}\rceil})$
两边同时平方(模数也要平方)
$B^2-2\ast B\ast B’+B’^2=0(\mod x^n)$
因为有个$B^2$不好计算,所以把等式两边同时乘上$A$
得到$B-2\ast B’+A\ast B’^2=0(\mod x^n)$
即$B=2\ast B’-A\ast B’^2(\mod x^n)$
这样就可以递归求解了
1 | Poly inv(Poly a, int n) { |
5.多项式除法
对于n次多项式$A$和m次多项式$B$,构造出小于n-m次多项式$C$和小于m次的多项式$D$
满足$A=B*C+D$
我们考虑一下多项式$A$的系数反转形式记做$RevA$
所以$RevA(x)=x^nA(\frac{1}{x})$
我们把原来的式子左右同时乘上$x^n$
得到$A(\frac{1}{x})\ast x^n=B(\frac{1}{x})\ast C(\frac{1}{x})\ast x^n+D(\frac{1}{x})\ast x^n$
所以$RevA(x)=RevB(x)\ast RevC(x)+x^{n-m+1}RevD(x)$
在$\mod x^{n-m+1}$的意义下发现$RevD$就没了,然而并不影响$RevA,RevB,RevC$
所以我们只需要求出$RevB$在$\mod x^{n-m+1}$意义下的逆元,然后就可以算出$RevC$和$RevD$
1 | Poly rev(Poly a) { |
6.多项式求导
因为多项式的形式很简单,所以求导直接可以模拟出来
1 | Poly deri(Poly a) { |
7.多项式积分
积分也直接模拟吧。。
1 | Poly inte(Poly a) { |
8.多项式对数函数
对于n次多项式$A$我们需要求出n次多项式$B$满足$B=\ln(A)$
两边同时求导
$B’=\frac{A’}{A}$
所以把$A$的导和逆乘起来然后积分回去就可以了。。
1 | Poly ln(Poly a) { |
9.多项式指数函数
对于n次多项式$A$我们需要求出来n次多项式$B$满足$B=e^A$
所以$\ln(B)=A $
然后我们构造一个函数$F(B)=\ln(B)-A$
我们要求函数$F(A)=0$的时候的解
根据泰勒展开和牛顿迭代:
$f(x)=f(x_0)+f’(x_0)(x-x_0)$
我们可以得到迭代公式:$x=x_0-\frac{f(x_0)}{f’(x_0)}$
对应到求exp上面来:$B=B_0-\frac{F(B_0)}{F’(B_0)}$
展开得到:$B=B_0-\frac{\ln(B_0)-A}{\frac{1}{B_0}}=B_0(1-\ln(B_0)+A)$
然后就可以根据上面的这个式子进行倍增,因为每一次计算长度会变成原来的两倍
1 | Poly exp(Poly a, int n) { |
10.多项式开根
给定n次多项式$A$,求$B$满足$B^2=A(\mod x^{n+1})$
和求exp的思路比较类似,同样用到了牛顿迭代法
构造函数$F(B)=B^2-A$,求$F(B)=0$的解
带入迭代公式:$x=x_0-\frac{f(x_0)}{f’(x_0)}$
得到$B=B_0-\frac{B_0^2-A}{2B_0}=\frac{B_0^2+A}{2B_0}=\frac{1}{2}\ast (B_0+\frac{A}{B_0})$
依旧是倍增进行求解
1 | Poly sqrt(Poly a, int n) { |