Polynomial_Industry
方便复习直接把重要的式子放在前面:
- 求逆,采用倍增,式子(牛顿迭代记忆可能比较方便?):
- 求导、积分与复合,即经典求导、积分与复合,式子:
- 牛顿迭代(非常重要):
- 开根,采用倍增(可以用牛顿迭代直接推):
- 多项式带余除法(换元翻转再取余):
- 多项式
(两边求导再积分):
- 多项式
,采用倍增(牛顿迭代推):
- 多项式快速幂:
方便粘板子直接把全家桶放 这里 了。
基本是复读 cmd 博客的。
模板题洛谷上基本都有。
占时没有 MTT 的东西(因为写不对)。。。
工业基础:NTT & FFT。
学完 NTT 后就可以来看这些操作了。
我们先把基本的模板贴在这里:
1 | #include<iostream> |
一、多项式求逆
递推法就不写了。。。
我们采用倍增。
首先,如果在
设
现在,假设我们已经得到了:
即逆元的前
显然:
移项一下:
然后平方一下:
拆开:
两边同乘
移项:
显然可以算了。
根据主定理:
所以最后时间复杂度
一个简单的实现方法是先求
然后可能还有什么优化方法,但是我不想用。。。
最后记得清空。
代码:
1 | // Inversion |
二、多项式牛顿迭代
关于求导、积分与复合。
定义多项式导数:
定义多项式积分:
定义多项式的复合:
积分使用前需要先线性求一波逆元。
代码:
1 | // Newton Iteration. |
关于多项式牛顿迭代:
若
证明:
显然
将
可知
可知
但上面的运算是
因为
这个式子很牛逼。
多项式求逆再推导
这个用牛顿迭代推导。求
的逆 。那么我们就有
。然后我们设
。则
。设
为 下的解。用上文牛顿迭代的式子:
上面的
就是 ,因为这俩多项式都是在 下的。然后就有了:
这玩意就是上面那个求逆的式子。
三、多项式开根
即
于是我们套路令
于是有
再根据牛顿迭代:
化简后就是:
这个东西可以倍增了(还要用一下求逆),时间复杂度可以用定积分推导(不关心这个的可以跳过):
我们积分近似一下:
积分线性性拆一下:
第一个还好,就是
第二个我去查了一下积分表:
然后这个我们就能算了:
注意
代码:
1 | // Squre root |
四、多项式带余除法
定义多项式带余除法,对于多项式
此时称
我们同样可以记作:
很容易想到,上面的
那么我们就要考虑如何让
我们知道
那么很自然想到翻转系数,原来次数低的系数变成次数高的。
定义
我们从
两边同时乘上
将我们上文定义的翻转操作代入:
这个时候我们将其置入
那么商就是:
求逆之后,翻转一下系数即可。
余数就是:
时间复杂度仍然是
代码:
1 | // Division with Remainder. Here f/g->f f%g->g. |
五、多项式 ,
两者均由麦克劳林级数定义:
这样我们的运算可以满足经典的一些性质。
多项式
这里我们有
。两边同时求导:
即(链式法则):
即:
再两边同时积分:
也就是说,一次求导,一次求逆,一次相乘,一次积分,我们就得到了
。时间复杂度
。多项式
这里就讲一个倍增方法。
已知
,即 。我们设
。求导可得
。套路牛顿迭代:
即:
根据上式倍增即可。
需要注意的是,必须保证
,此时 。与上文多项式开根的复杂度分析类似,使用定积分可以得到
的时间复杂度是 的。
代码:
1 | // Ln & Exp. |
六、多项式快速幂
有了上面的操作,这个东西就变得简单了起来:
也就是说,一次
时间复杂度
关于加强版,因为巨神的码被 Hack 了,我也懒得管,所以就不做了。
代码:
1 | // Qpow. |
七、任意模数多项式乘法
咕咕咕。