下面其實是寫給自己查閱的,真正要學可以看上面的。
oi裡的fft並沒有那麼神奇,可以簡單理解為加速卷積(多項式)的工具。
設n次多項式a,b,本來需要n^2的時間求其乘積(卷積),使用fft可以加速成n log n.
#n次單位複數根
滿足w^n=1的複數。
由複數乘法性質,幅角相加,長度相乘可知,w其實就是將單位圓均分為n份的那n個複數。
記為w1,…wn.
顯然w j=
cos(
j∗2p
i/n)
+sin
(j∗2
pi/n
)∗iwj=cos(j*2pi/n) + sin(j*2pi/n)*i
wj=cos
(j∗2
pi/n
)+si
n(j∗
2pi/
n)∗i
#dft
離散傅利葉變換(求點值表達,下文點值表達特指x取遍n次單位複數根的點值表達)
下文稱a次多項式的次數界為a+1。
為了方便,次數界應補足為最近的2的冪。 (高位係數設0)
求乙個次數界為n的多項式,當x取n單位複數根時(w0…wn-1)的n個值。
主要思想是分治,拆分為奇數冪次與偶數冪次,由於單位複數根的特殊性質(平方後減半)
最終式子:
a [i
]=a0
[i]+
a1[i
]∗wi
,i2a[i]~~~~~~~~~~~=a0[i] + a1[i] * w^i,ia[
i]=a
0[i]
+a1[
i]∗wi,i
2a[i+
n/2]
=a0[
i]−a
1[i]
∗wi,
i2a[i+n/2]=a0[i] -a1[i] * w^i,ia[
i+n/
2]=a
0[i]
−a1[
i]∗wi,i
2 #逆dft
已知次數界為n的多項式在n次單位複數根下的點值表達,求係數表達。
一發推導後可以發現,只要把n次主根取w−1
w^w−
1,按照原先做dft,再將最後結果/次數界即可。
最終結果可能有誤差,需要加上乙個eps.
#蝶形變換
小常數實現fft的方法。
先按二進位制翻轉(上限取次數界-1),然後從左到右做。
#ntt (數論變換)
模意義下的dft/idft
在模乙個費馬模數的前提下(p=k
2a+1
p=k2^a+1
p=k2a+
1,比如998244353,g=3),我們可以將n次單位主根單位根替換為gp−
1ng^ }
gnp−1
,其中g是p的原根。
且滿足n<=2^a
假設乙個數g是p的原根,那麼g^i mod p的結果兩兩不同,且有 1<
g0<
i1<
g0<
i逆dft中,負指數需要用逆元。注意long long問題
#除錯方法
無???
如何驗證對錯:
對拍觀察fft後虛部是否為0。
對乙個數列dft,idft看是否前後一致
#dft
#include #include #include #include typedef double db;
typedef long long ll;
#define com complexusing namespace std;
const int n=1e5+10;
const db pi=acos(-1);
int n,h[n*6],m;
com q[n*6],r[n*6];
com a[n*6];
void dft(com *src,int sig)
void
ntt(
int*a,
int sz,
int sig)}}
}int
main()
FPGA入門板子的選購
板子的型別 開發板 核心板 微控制器的區別 開發板 把核心板 外圍電路板整合。嵌入式系統開發的電路板,包括cpu 儲存器 i o裝置 線路和外部資源介面等一系列硬體元件。核心板 把微控制器集成為一塊板子。將mini pc的核心功能打包封裝。大多數整合了cpu 儲存器和引腳,通過引腳與配套底板連線,實...
FFT 留個板子(後續可能還有FWT,NNT等)
用於解決多項式乘法 樸素n 2,fft nlogn 洛谷 多項式乘法 include define n 8000005 using namespace std const double pi acos 1.0 struct complexx a n double coss n sinn n int ...
FFT簡單解釋
謝謝作者 fft是離散傅利葉變換的快速演算法,可以將乙個訊號變換到頻域。有些訊號在時域上是很難看出什麼特徵的,但是如果變換到頻域之後,就很容易看出特徵了。這就是很多訊號分析採用fft變換的原因。另外,fft可以將乙個訊號的頻譜提取出來,這在頻譜分析方面也是經常用的。雖然很多人都知道fft是什麼,可以...