天上掉下来的FFT

2024-02-20 15:59
文章标签 下来 fft 天上掉

本文主要是介绍天上掉下来的FFT,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

FFT

本文学习借鉴 Link 董晓算法

说实话董老师讲的太好了

前言

闲来无事,点了一下随机跳题。

LUOGU 4461 [CQOI2018] 九连环

读完题随便一写, O ( n ) O(n) O(n) 的转移(当时很激动,毕竟以为秒了紫题)。反手一交 30 p t s 30pts 30pts 仔细一看,这题居然没有让去模!?!(开始发癫。

FFT 前置芝士

虚数的意义

我们将坐标系上的点可以这样理解:

n n n 看作实部 m m m 看作虚部,即点 A = n + i m A = n + im A=n+im

呢我们就可以用半径和角度表示一个圆上的点。

如点 A = cos ⁡ θ ⋅ r + i ⋅ sin ⁡ θ ⋅ r A = \cos \theta \cdot r + i \cdot \sin \theta \cdot r A=cosθr+isinθr

则利用 π \pi π 来表示角度,钦定将圆分成 n n n 份这个角度占 k k k 份,再钦定 r = 1 r = 1 r=1 就出现了一个神奇的表示:

单位根 ω n k = cos ⁡ 2 π k n + i ⋅ sin ⁡ 2 π k n \omega ^ k _ n = \cos \frac {2 \pi k} {n} + i \cdot \sin \frac {2 \pi k}{n} ωnk=cosn2πk+isinn2πk

其有一些神奇且具象的性质:

周期性 : ω n k = ω n k + n \omega ^ {k} _ {n} = \omega ^ {k + n} _ {n} ωnk=ωnk+n

很好理解就是转一圈回到原点.

对称性 : ω n k + n 2 = − ω n k \omega ^ {k + \frac{n}{2}} _ {n} = - \omega ^ {k} _ {n} ωnk+2n=ωnk

形如上图点 C 和点 D,转了 180 度相当于原数取反.

折半性 : ω 2 n 2 k = ω n k \omega ^ {2k} _ {2n} = \omega ^ {k} _ {n} ω2n2k=ωnk

相当于分子分母化简,也很好理解 你在分成 8 份时取 4 份和在 4 份中去 2 份意义相同.

虚数乘

A = a 1 + i ⋅ a 2 , B = b 1 + i ⋅ b 2 A = a_1 + i \cdot a_2 , B = b_1 + i \cdot b_2 A=a1+ia2,B=b1+ib2

A × B = ( a 1 + i ⋅ a 2 ) × ( b 1 + i ⋅ b 2 ) A \times B = ( a_1 + i \cdot a_2 ) \times(b_1 + i \cdot b_2) A×B=(a1+ia2)×(b1+ib2)

= a 1 b 1 + i 2 a 2 b 2 + i ( a 2 b 1 + a 1 b 2 ) = a_1b_1 + i^2a_2b_2 + i(a_2b_1 + a_1b_2) =a1b1+i2a2b2+i(a2b1+a1b2)

= a 1 b 1 − a 2 b 2 + i ( a 2 b 1 + a 1 b 2 ) = a_1b_1 - a_2b_2 + i(a_2b_1 + a_1b_2) =a1b1a2b2+i(a2b1+a1b2)

开始正题

众所周知 , 一个 n n n 阶多项式可以用 n n n 个点来唯一确定.

对于长度为 n n n 的多项式

A ( x ) = a 1 + a 2 x + a 3 x 2 ⋯ a n + 1 x n A(x) = a_1 + a_2x + a_3x^2 \cdots a_{n+ 1}x^n A(x)=a1+a2x+a3x2an+1xn

我们可以间其奇数次幂和偶数次幂分离(别问为什么这样做,我感觉 FFT 的思路就是天上掉下来的)

奇数次幂 : ( a 1 x + a 3 x 3 ⋯ a n − 1 x n − 2 ) = ( a 2 + a 4 x 2 ⋯ a n x n ) ⋅ x (a_1x + a_3x^3 \cdots a_{n - 1}x^{n - 2}) = (a_2 + a_4x^2 \cdots a_{n}x^{n}) \cdot x (a1x+a3x3an1xn2)=(a2+a4x2anxn)x

偶数次幂 : ( a 0 + a 2 x 2 ⋯ a n − 2 x n − 2 ) (a_0 + a_2x^2 \cdots a_{n - 2}x^{n - 2}) (a0+a2x2an2xn2)

设:

A 1 ( x ) = ( a 0 + a 2 x 2 ⋯ a n − 2 x n 2 − 1 ) A_1(x) = (a_0 + a_2x^2 \cdots a_{n - 2}x^{\frac n 2 - 1}) A1(x)=(a0+a2x2an2x2n1)

A 2 ( x ) = ( a 1 + a 3 x 2 ⋯ a n − 1 x n 2 − 1 ) A_2(x) = (a_1 + a_3x^2 \cdots a_{n - 1}x^{\frac n 2 -1}) A2(x)=(a1+a3x2an1x2n1)

A ( x ) = A 1 ( x 2 ) + A 2 ( x 2 ) ⋅ x A(x) = A_1(x ^ 2) + A_2(x ^ 2) \cdot x A(x)=A1(x2)+A2(x2)x

用前面的单位根往里带(评价为天上掉下来的)

图片来自董老师 Link 董晓算法

发现如果 n = 2 k n = 2 ^ k n=2k 就可以直接二分到底,所有我们钦定 n = 2 k n = 2 ^ k n=2k .

可以直接递归到底然后再反推回来.

我们就可以得到 n 个点

求出 多项式 A 和 B 把每个点乘起来,再把单位根的倒数带入将点值转话为 z i = a i ⋅ n z_i = a_i \cdot n zi=ain

图片来自董老师 Link 董晓算法

所有 a i = z i n a_i = \frac {z_i} n ai=nzi 就得到答案了!

优化

递归显然是不优雅的

我们观察最终搜索到的序列,

图片来自董老师 Link 董晓算法

观察发现每个数字的结果其实就是将原数的二进制倒过来

称之为蝴蝶变化.

这时候 zxc 大佬就要开始发癫了

如何求呢?

观察发现 f[i] = f[i / 2] / 2 + [i & 1] * n / 2;

所有我们就可以 O ( n ) O(n) O(n) 推出变化 O ( n log ⁡ n ) O(n \log n) O(nlogn) 得到答案.

这篇关于天上掉下来的FFT的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/728746

相关文章

拼多多为何主动“慢”下来进行商家生态治理?

十几天前的财报电话会上,拼多多管理层向外界释放了两个关键信息: 一是将通过“扶持与治理”并举的方式,继续完善生态建设,未来一年将投入百亿资源包扶持新质商家,减免100亿商家交易手续费,并坚决地进行商家生态治理。目前,拼多多的“百亿减免计划”已经相继落地,先后推出多项服务费退免、下调店铺保证金、升级商家售后服务体系等。 二是对未来增长的理性预判,“拼多多的盈利曲线并非是线性的”、“过去几个季度的

项目依赖拉不下来卡着不动怎么办,node又不支持cnpm

如果你的项目依赖在拉取时卡住,可以尝试以下步骤来解决问题: 检查网络:确保你的网络连接稳定。如果可能,尝试使用 VPN 或更换网络。 使用镜像源:   对于 yarn,可以使用淘宝镜像: yarn config set registry https://registry.npmmirror.com/ 对于 npm,可以临时使用淘宝镜像: npm config set registry

【数字信号处理】一文讲清FFT(快速傅里叶变换)

目录 快速傅里叶变换(Fast Fourier Transform,FFT)FFT的背景快速傅里叶变换(Fast Fourier Transform,FFT)DFT的数学表达实际计算重要性和应用频谱泄露、频谱混叠奈奎斯特采样定理参考链接 快速傅里叶变换(Fast Fourier Transform,FFT) FFT的背景 1、为什么要时域→频域频率?50Hz+频率120Hz

【BNU】40719 Arithmetic Progressions【分块+FFT】

传送门:【BNU】40719 Arithmetic Progressions 题目分析: 用分块+FFT强行AC了这题…… 之前一直TLE……然后改了好久把姿势改的优美点了……终于过了…… 大概思路是:我们考虑分块,假设每一块的大小为S,一共分了B块然后我们分两种情况讨论: 1.第二个数在第i块,第一个数在(1~i-1)块内,第三个数在(i+1~B)块内。 2.至少两个数在同一块内。

【HDU】5197 DZY Loves Orzing 【FFT启发式合并】

传送门:【HDU】5197 DZY Loves Orzing 题目分析: 首先申明,我不会 dp dp方程= =……这个东西给队友找出来了,然后我就是套这个方程做题的Qrz…… 对于这题,因为 n2 n^2个数互不相同,所以每一列都可以单独考虑。设 dpni dp_ni表示长度为 n n的排列,能恰好看见ii个人的方案数,根据队友的发现, dpni dp_ni就等于 |sni| |s_ni|

【ZOJ】3874 Permutation Graph 【FFT+CDQ分治】

传送门:【ZOJ】3874 Permutation Graph 题目分析: 容易知道一个个连通块内部的标号都是连续的,否则一定会有另一个连通块向这个连通块建边,或者这个连通块向另一个连通块建边。而且从左到右左边的连通块内最大的标号小于右边连通块内最小的标号。 然后我们可以构造dp方程: dp[n]=n!−i!∗dp[n−i] \qquad \qquad dp[n] = n! - i! *

【SPOJ】Triple Sums【FFT】

传送门:【SPOJ】Triple Sums 题目分析: 首先我们不考虑 i<j<k i<j<k这个条件,构造多项式: Y=∑xai \qquad\qquad\qquad Y = \sum x^{a_i} 那么 ai+aj+ak=S ai+aj+ak=S的个数即 xai+aj+ak=S x^{a_i+a_j+a_k=S}的个数,等价于 Y3中xS Y^3中x^S的系数。 然后我们考虑容斥

【BNU】33943 Super Rooks on Chessboard 【FFT】

【BNU】33943 Super Rooks on Chessboard UVA上的题,然而我怎么会蠢到去UVA呢!(其实是百度首先跳出来的是BNU → \to_ → \to) 题目分析: 设 numx numx为 N N个车没有覆盖的行数,numynumy为 N N个车没有覆盖的列数。 首先我们考虑没有主对角线覆盖这一条件时,总共的没有被覆盖的面积就是numx∗numynumx \ast

【HDU】4609 3-idiots 【FFT】

传送门:【HDU】4609 3-idiots 题目分析: 我们考虑两边长度之和为 n n的方案数,设num[x]num[x]为长度为 x x的个数,那么∑nx=1num[n−x]∗num[x]\sum_{x=1}^{n}{num[n-x]*num[x]} 即两边长度之和为 n n的方案数。容易发现这这正是卷积!然后我们就可以愉快的用FFTFFT预处理出所有的两边长度之和为i的方案数。 FFT

【codechef】 Prime Distance On Tree【求树上路经长度为i的路径条数】【点分治+FFT】

传送门:【codechef】 Prime Distance On Tree 点分治+FFT水题……竟然n*n爆int没发现…… 而且NTT TLE,FFT跑的超级快…… my  code: my~~code: #include <bits/stdc++.h>using namespace std ;typedef long long LL ;#define clr( a , x ) m