多项式的基本运算(FFT和NTT)总结

设参与运算的多项式最高次数是n,那么多项式的加法,减法显然可以在O(n)时间内计算。

所以我们关心的是两个多项式的乘积。朴素的方法需要O(n^2)时间,并不够优秀。

考虑优化。

多项式乘积

方案一:分治乘法。

对于多项式X,Y,假设各有2m项,(即最高次数是2m-1)

X,Y分别可以用两个含m项的多项式来表示,即:

由此可见,为了计算XY,只需计算出AC, (A+B)(C+D), BD,然后用多项式加减法求得XY即可。

设含有m项的多项式相乘的时间为T(m)

于是容易算出时间复杂度是,约等于

以上方法的优点在于,代码难度低,思维难度低,多项式系数任意,对运算没有任何限制。

缺点在于:太慢了!

方案二:FFT / NTT

这种方法除了快之外,没有任何优点。但仍是一种好方法。

FFT的详细推导不再描述,这里只是简单的总结。

对于多项式乘法,有一种思路,

a. 是先从系数表示法转换为点值表示法,

b. 然后乘起来(得到乘积式的点值表示法),

c. 最后从点值表示法转变回系数表示法。

对于操作a,很容易做到O(n^2),

对于操作b,很容易做到O(n),

对于操作c,用高斯消元可以做到O(n^3),用拉格朗日插值法可以做到O(n^2)。

FFT则是利用了单位根的性质,将操作a和操作c优化到了O(nlogn)。

虽然在复数域中永远存在单位根,但是容易出现精度问题。

NTT并没有用复数域的单位根。

当某两个多项式相乘,系数对某一模数取模的时候,必须存在2^k次(2^k>=2n)单位根,且必须存在2的逆元。

当模数p是形如 998244353 的质数时,998244353 = 7 × 17 × 2^23 + 1,( 2^k | phi(p) )

设p的原根是g,则模p意义下,2^k次单位根是

当模数并不是满足要求的模数,我们可以知道,一次多项式乘法的结果,每一位上的数不超过n*p*p。

我们可以取多个不同的NTT模数,使得它们的乘积大于n*p*p。对每一个NTT模数做一次多项式乘法,最后用中国剩余定理计算即可。

多项式求逆

我们定义多项式A的乘法逆元B,满足A*B=1。

多项式求逆能解决多项式除法等一系列问题,因为X/Y=X*Y的逆元。

我们首先证明,多项式A存在乘法逆元的充要条件是A的常系数存在逆元。

必要性显然,因为A的常数项*B的常数项=1。

由此,我们可以求出B的常数项,接着推出一次项系数,二次项系数...

所以乘法逆元存在且唯一,充分性同样显然。

为了求逆元,一种方法是O(n^2),即先求常数项,再推出一次项系数,继续推完整个多项式。

还有一种用O(nlogn)时间计算乘法逆元的方法,

先求出A(x)的常数项的逆元b,初始化B(x)=b,则

当前状态:若

那么

两边平方

于是

所以继续这样的操作,每次多项式乘法用fft运算,最终可以求出A(x)的乘法逆元。

设多项式项数是n,

时间: 2024-10-13 21:20:06

多项式的基本运算(FFT和NTT)总结的相关文章

多项式fft、ntt、fwt 总结

做了四五天的专题,但是并没有刷下多少题.可能一开始就对多项式这块十分困扰,很多细节理解不深. 最简单的形式就是直接两个多项式相乘,也就是多项式卷积,式子是$N^2$的.多项式算法的过程就是把卷积做一种变换,在变换后各系数相称得到新系数.其实这一步变换的构造过程挺深奥的,并不是很会.对于多项式卷积的变换就是点值.于是就有了快速变换这样的算法. 细节问题出过很多.边界的问题容易弄错.一般如果是两个N项多项式相乘,得到的是一个$2*N-1$项的多项式,这是存在系数的,只不过一般我们只要N项的结果,所以

FFT及NTT学习

贴上学习FFT和NTT的资料,以后再补题吧 http://blog.miskcoo.com/2015/04/polynomial-multiplication-and-fast-fourier-transform#i-15 http://blog.csdn.net/acdreamers/article/details/39005227 http://blog.csdn.net/acdreamers/article/details/39026505

洛谷P3803 【模板】多项式乘法(FFT)

P3803 [模板]多项式乘法(FFT) 题目背景 这是一道FFT模板题 题目描述 给定一个n次多项式F(x),和一个m次多项式G(x). 请求出F(x)和G(x)的卷积. 输入输出格式 输入格式: 第一行2个正整数n,m. 接下来一行n+1个数字,从低到高表示F(x)的系数. 接下来一行m+1个数字,从低到高表示G(x))的系数. 输出格式: 一行n+m+1个数字,从低到高表示F(x)∗G(x)的系数. 输入输出样例 输入样例#1: 复制 1 2 1 2 1 2 1 输出样例#1: 复制 1

多项式艺术:浅谈FFT和NTT算法(未完待续)

什么是多项式? 百度百科说:“由若干个单项式相加组成的代数式叫做多项式.多项式中每个单项式叫做多项式的项,这些单项式中的最高次数,就是这个多项式的次数.” 也就是说,形如的式子,就叫做多项式.这样的式子,也能写作.很显然,多项式加上(或是减上)多项式也是多项式,复杂度是的.但是,如果多项式想要乘上一个多项式,那么也可以,最简单的方法却是的. 不过,FFT算法会告诉你,就够了. 多项式乘法 我们说的,多项式想要乘上一个多项式,那就是多项式乘法,人称“卷积”.我们方才所看到的,被称为多项式的“系数表

FFT与NTT

多项式: 多项式我也不懂... 多项式加法: 同类项系数相加: 多项式乘法: A*B=C $A=a_0x^0+a_1x^1+a_2x^2+...+a_ix^i+...+a_{n-1}x^{n-1}$ $B=b_0x^0+b_1x^1+b_2x^2+...b_ix^i+...+b_{m-1}x^{m-1}$ 则 $C=c_0x^0+c_1x^1+c_2x^2+...c_ix^i+...+c_{m+n-2}x^{m+n-2}$ 其中 $$c_k=\sum_{i+j=k}^{i<n,j<m}a[i]

洛谷P3803 【模板】多项式乘法(FFT) 【fft】

题目 这是一道FFT模板题 输入格式 给定一个n次多项式F(x),和一个m次多项式G(x). 请求出F(x)和G(x)的卷积. 输出格式 第一行2个正整数n,m. 接下来一行n+1个数字,从低到高表示F(x)的系数. 接下来一行m+1个数字,从低到高表示G(x))的系数. 输入样例 一行n+m+1个数字,从低到高表示F(x)?G(x)的系数. 输出样例 1 2 1 2 1 2 1 提示 1 4 5 2 题解 表示迭代还不是很懂 只好背模板... #include<iostream> #incl

luogu P3803 【模板】多项式乘法(FFT)

题目背景 这是一道 FFT 模板题 题目描述 给定一个 n 次多项式 F(x),和一个 m 次多项式 G(x). 请求出 F(x) 和 G(x) 的卷积. 输入格式 第一行 2 个正整数 n,m. 接下来一行 n+1 个数字,从低到高表示 F(x) 的系数. 接下来一行 m+1 个数字,从低到高表示 G(x) 的系数. 输出格式 一行 n+m+1 个数字,从低到高表示 F(x)*G(x) 的系数. #include<cmath> #include<cstdio> #include&

[拉格朗日反演][FFT][NTT][多项式大全]详解

1.多项式的两种表示法 1.系数表示法 我们最常用的多项式表示法就是系数表示法,一个次数界为\(n\)的多项式\(S(x)\)可以用一个向量\(s=(s_0,s_1,s_2,\cdots,s_n-1)\)系数表示如下:\[S(x)=\sum_{k=0}^{n-1}s_kx^k\] 系数表示法很适合做加法,可以在\(O(n)\)的时间复杂度内完成,表达式为:\[S(x)=A(x)+B(x)=\sum_{k=0}^{n-1}(a_k+b_k)x^k\] 当中\[s_k=a_k+b_k\] 但是,系数

CodeForces 958F3 Lightsabers (hard) 启发式合并/分治 多项式 FFT

原文链接http://www.cnblogs.com/zhouzhendong/p/8835443.html 题目传送门 - CodeForces 958F3 题意 有$n$个球,球有$m$种颜色,分别编号为$1\cdots m$,现在让你从中拿$k$个球,问拿到的球的颜色所构成的可重集合有多少种不同的可能. 注意同种颜色球是等价的,但是两个颜色为$x$的球不等价于一个. $1\leq n\leq 2\times 10^5,\ \ \ \ \ 1\leq m,k\leq n$. 题解 来自Hel