题目链接
3122. 多项式乘法
题目描述
给定一个 n 次多项式 F(x)=a0+a1x+a2x2+…+anxn。
以及一个 m 次多项式 G(x)=b0+b1x+b2x2+…+bmxm。
已知 H(x)=F(x)⋅G(x)=c0+c1x+c2x2+…+cn+mxn+m。
请你计算并输出 c0,c1,…,cn+m。
输入格式
第一行包含两个整数 n,m。
第二行包含 n+1 个整数 a0,a1,…,an。
第三行包含 m+1 个整数 b0,b1,…,bm。
输出格式
共一行,依次输出 c0,c1,…,cn+m。
数据范围
1≤n,m≤105,
0≤ai,bi≤9
输入样例:
输出样例:
解题思路
fft
一个 n−1 次多项式 f(x)=a0+a1×x1+a2×x2+⋯+an−1×xn−1可以由 n 个 (xi,f(xi)) 点唯一表示
证明:
即求解 n 元一次方程的 ai,将其系数用行列式表示出来:
∣∣
∣
∣
∣
∣∣1x1⋯xn−111x2⋯xn−12⋮⋮⋮1xn⋯xn−1n∣∣
∣
∣
∣
∣∣
即该系数行列式即为范德蒙行列式的转置,故其值为:∏1≤j<i≤n(xi−xj),而 xi≠xj,故其值不为 0,而一个一次 n 元方程组有唯一解则其系数行列式不为 0,故其解唯一,所以一个 n−1 次多项式可以由 n 个点唯一表示
一般 fft 都是用来求解多项式的卷积(乘积),暴力做法的复杂度为 O(nm),而 fft 利用上述性质,即将其转化为点表示法,利用点表示法求出结果的点表示法,最后再将点表示法转化为系数表示法,例如:f(x)=g(x)×h(x),将 g(xi) 和 h(xi) 转化为点表示法,f(x) 共 n+m 项,g(x) 和 h(x) 不足的补零,将对应的共同的 xi 的 g(xi) 和 h(xi) 相乘,得 f(x) 的点表示法,最后再将点表示法转化为系数表示法,而点表示法和系数表示法的相互转化的复杂度为 O(nlogn),即 fft 的复杂度为 O((n+m)×log(n+m))
所以 fft 的关键在于点表示法和系数表示法的相互转化
系数表示法转化为点表示法
其中点当然也可以是复数,故这 n 个点可以为单位圆上辐角均分的 n 个点,用 wkn 表示为第 k 个点,其表示的复数为 (cos(2π×kn),sin(2π×kn)),另外要用到的复数乘法的一些性质:乘法后的复数模长为两复数模长相乘,辐角为两复数辐角相加,则有 wk+n2n=−wkn,w2k2n=wkn
设一个 n−1 (n 为 2 次幂)次多项式 A(x)=a0+a1x+a2x2+⋯+an−2xn−2+an−1xn−1
设:
A1(x)=a0+a2x2+⋯+an−2xn2−1A2(x)=a1+a3x1+⋯+an−1xn2−1
则有 A(x)=A1(x2)+xA2(x2)
假设 0≤k<n2 ,将 x=ωkn 代入,得
A(ωkn)=A1(ω2kn)+ωknA2(ω2kn)
将 x=ωk+n2n 代入,得
A(ωk+n2n)=A1(ω2k+nn)+ωk+n2nA2(ω2k+nn)=A1(ω2kn)+ωk+n2nA2(ω2kn)=A1(ω2kn)−ωknA2(ω2kn)
即如果知道一半的 A(ωkn),则可以知道另一半的 A(ωk+n2n),另外每次都能将原问题的求解规模缩小一半,故其时间复杂度为 O(nlogn)
由于 fft 的递归写法常数巨大,故一般采用迭代写法,例如:
a0 a1 a2 a3 a4 a5 a6 a7–––––––––––––––––––––––a0 a2 a4 a6––––––––––– a1 a3 a5 a7––––––––––––a0 a4––––– a2 a6–––––– a1 a5–––––– a3 a7––––––a0––– a4––– a2––– a6––– a1––– a5––– a3––– a7–––
其中最上层的 ai 表示按多项式顺序的值,最下层表示初始时的 ai,例如 a0 由下层的 a0 和 a1 计算得到,其他同理。迭代需要最底层的数,最底层的数的下标和原数的下标之间有什么关系?下标的二进制之间互为翻转关系(蝴蝶变换)。简略证明:如果一个数为奇数,即二进制下最低位为 1,则其一定在另外一半中出现,而另外一半最高位都为 1,即最高位和最低位满足翻转关系,同理不考虑最高位和最低位的情况下其他位也满足翻转关系。得到最底层,往上计算即得点表示法,具体计算:设置一个变量 mid,表示当前区间数需要计算的次数,由于每次只需计算一半,2×mid 即当前区间数,i 为每个区间开始的位置,j 为每个区间的位置变量,i+j 即为每个区间中多项式对应的值,据此递推计算即可
点表示法转化为系数表示法
设一个 n−1 (n 为 2 次幂)次多项式 A(x)=a0+a1x+a2x2+⋯+an−2xn−2+an−1xn−1,由迭代过程得到 n 个多项式的值 yi,则 ak=∑n−1i=0yi(ω−kn)in
证明:∑n−1i=0yi(ω−kn)i=∑n−1i=0∑n−1j=0aj(ωin)j(ω−kn)i=∑n−1j=0aj∑n−1i=0(ωj−kn)i
设 s(x)=1+x+x2+⋯+xn−1,则如果 k≠0,s(ωkn)=1+ωkn+ω2kn+⋯+ω(n−1)kn,而 ωkns(ωkn)=ωkn+ω2kn+⋯+ωnn=s(ωkn),而 ωkn≠0,则 s(ωkn)=0,如果 k=0,则 s(ωkn)=n。故 ∑n−1j=0aj∑n−1i=0(ωj−kn)i 当且仅当 j=k 时 ∑n−1i=0(ωj−kn)i≠0,且其等于 n,故 ∑n−1j=0aj∑n−1i=0(ωj−kn)i=nak,得证
知道这个有什么用处呢? 设 g(x)=∑n−1i=0yixi,则 ak=g(ω−kn)n,即可以利用转化为点表示法的过程求解系数表示法
- 时间复杂度:O((n+m)×log(n+m))
代码
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!