FFT&NTT&FWT
高二了还不会 FFT ?
FastFourierTransform(FFT) 在 oi 中的主要作用是用来求“卷积”(多项式乘法)。
可将时间复杂度降为 O(nlog2n)
3步快速求出多项式乘积:
- 由系数表示法转换成点值表示法。
- 求两个多项式的乘积。
- 将点值表示法转换成系数表示法。
假设A的点值表达式为(x0,y0),(x1,y1),(x2,y2)...
假设B的点值表达式为(x0,y10),(x1,y11),(x2,y12)...
那么C的点值表达式为(x0,y0y10),(x1,y1y11),(x2,y2y12)...
接下来分析1.
将一个 n 次项的多项式分成奇函数,偶函数两个部分。
接下来考虑如何选点获得点值。
对于一个奇函数,求出一组 (x,y) 的值,同时可得到 (−x,−y)
对于一个偶函数,求出一组 (x,y) 的值,同时可得到 (−x,y)
所以我们可以通过函数的性质,求出一个点的坐标就能得到两个点的坐标。一个 d 阶的多项式需要 d+1 个点,所以只需要求 d/2 次点即可。
将原多项式转化为两个子问题递归求解,于是时间复杂度降到 log 级别。
但是,真的如此吗?
注意到对于每个求值点对应的坐标都为平方数,所以都是正的,上述关于正负推出的递归显然不成立。
有点伤心。
那找到平方为负数的数是不是问题就解决了?
好。复数上场。
考虑复数的三角恒等变换。开始推。
n 次单位复数根是满足 ωn=1 的复数 ω
注意到 k 阶单位复数根即为ω1k
由折半定理,得到:如果 n 是大于 0 的偶数,那么 n 的 n 个单位复数根的平方的集合就是 n/2 的 n/2 个单位复数根的平方的集合。
注意到,由折半定理我们发现前半部分的值和后半部分的值相同,这样问题就被分成两个子问题,再对这两个子问题进行递归求解即可。
这样2.完成。
那么对于3.就很简单,通过矩阵乘法,将点值转化为系数只需要将点值表达式再做一遍FFT,最后每项除以长度即可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战