FFT
作者:陈犇
FFT教程
标签(空格分隔): 数学 ACM
FFT是什么?
FFT是快速傅里叶变换(fast Fourier transform)的简称。在ACM领域主要是用来快速求解多项式乘法的算法,
在信号领域也有很大用途
基础知识
卷积
举个例子,给你两个向量a(a0,a1,a2),b(b0,b1,b2)
a和b的卷积就是(a0∗b0,a1∗b0+a0∗b1,a2∗b0+a1∗b1+a0∗b2,a1∗b2+a2∗b1,a2∗b2)
即可以看作两个多项式A(x)=a0+a1x1+a2x2和B(x)=b0+b1x+b2x2 相乘。
所以卷积就可看做多项式乘法。那些形如ck=Σki=0aibk−i 卷积的就可以类比成多项式乘法 ,就可通过fft快速求解。-
多项式
- 多项式有两种表达形式
- 一种是系数表达形如
A(x)=Σn−1i=0aixi - 另一种是点值表达, 形如
(x1,y1),(x2,y2),(x3,y3)...(xm,ym) , 且m>=n - 多项式的点值表示和插值表示可以互推
-
wn=e2πi/n -
wn/2+kn=−wkn -
w2kn=wkn/2 -
Σn−1j=0wjkn=(k%n==0)?n:0
-
傅里叶变换的原理
在傅里叶变换里面系数表达和点值表达如何互推?
一个暴力点的方法
系数表达->点值表达
点值表达->系数表达
证明看黑板
所以不论是系数表达推点值表达还是点值表达推系数表达方法都一样
如何快速的求出上面的式子呢
假设
那
令
则
那么就可以用
得出
分治图
void ntt(ll* a, int n, int t) {
rep(i, 0, n) {
int rv = rev(i,n);
if(i<rv) swap(a[i], a[rv]);
}
ll g=1;
if(t==1) g=3;
else g=inv[3];
for(int m=2; m<n+1; m<<=1) {
ll wm= mypow(g, (MOD-1)/m);
int mid=m>>1;
for(ll *p=a; p<a+n; p+=m) {
ll w=1;
rep(i, 0, mid) {
ll t=w*(p[mid+i]);
p[mid+i] = p[i]-t;
p[i] = p[i]+t;
w = w*wm%MOD;
p[i]=%MOD, p[mid+i]%=MOD;
}
}
}
if(t==-1) {
rep(i, 0, tn)
a[i]=a[i]*inv[n]%MOD;
}
}
void fft(ll *a, ll* b, int n) {
int tn=MAXN;
while(tn/4>=n) tn>>=1;
ntt(a, tn, 1);
ntt(b, tn, 1);
rep(i, 0, tn)
a[i] = a[i]*b[i]%MOD;
ntt(a, tn, -1);
}
NTT wn=g(P−1)/n%P
上一篇: Git教程及常用命令
下一篇: 20200412 T2 带mod的FFT
推荐阅读
-
Python实现快速傅里叶变换的方法(FFT)
-
洛谷P1919 【模板】A*B Problem升级版(FFT快速傅里叶)
-
BZOJ4259: 残缺的字符串(FFT 字符串匹配)
-
BZOJ4827: [Hnoi2017]礼物(FFT 二次函数)
-
matlab2c使用c++实现matlab信号操作函数awgn、normrnd、fft、sawtooth、sinc、signcdf、signpdf
-
SCUT - 271 - CC 非诚勿扰 - FFT
-
音频处理六:(音频的反FFT)
-
Python之数据分析(Numpy的子模块:线性代数模块linalg、傅里叶变换模块fft)
-
STM32F4使用FPU+DSP库进行FFT运算的测试过程一
-
BZOJ 3771: Triple(生成函数 FFT)