FFT學習筆記

2022-05-29 05:30:09 字數 2160 閱讀 9658

很早就想學fft那套理論,但抱著能咕一天是一天的態度咕到了今天

fft是幹什麼的?

求兩個多項式卷積的,比如$g=a*b$($g_x=\sum}$)

顯然暴力乘是$o(n^2)$的,然而我們可以把他優化到$o(n\;log\;n)$

一般來將,多項式是用每一項的係數表示的,而還可以用點值來表示,比如乙個多項式$a$有n項,我們可以讓變數x取n個不同的值,然後用n個得出來的值表示這個多項式

由於是點值,兩個多項式相乘時只要把對應的點值相乘即可,這是$o(n)$的

顯然我們容易可以把兩個表示法互相轉換,比如$n^2$暴力和$n^3$高斯消元

這似乎比暴力還要不優越,所以我們要優化轉化表示法的複雜度

我們發現我們可以隨便選數x,只要x各不相同就行,然而當x在大部分取值時,都要暴力算$x^i$的值,這很不優越

所以我們的數學知識告訴我們數不只有實數,還有虛數啊懶得介紹虛數,我去拖一點東西過來

虛數大概就是可以表示在乙個復平面上的東西,k次單位根$w_k$就是其k次方是1的東西$w_k$的i次方都在乙個以原點為圓心,1為半徑的圓上

由於複數運算的種種性質(幅角相加,長度相乘),這些東西是繞原點順時針的,然後我們把i次單位根代入多項式來求值,這就是可以優化的了

然後我們就可以用分治來優化啦

把多項式分成奇數項和偶數項兩部分然後分治,就像這樣

愉快地盜了張圖來 原文

由於要按照奇偶性分治,分治後的順序會和原來不同,為了讓實現更方便,可以把原下標的二進位制翻轉後當新下標(不會證)

那麼我們就可以把係數表示變成點值表示了,這就是dft

然後怎麼把點值還原成係數呢,據說只要把點值除第一項的、部分翻轉,然後跑dft,再把結果除以n就好了(還是不會證)

大概就這樣吧我感覺講的海星

例題有這個(

模板)多項式乘法(fft)

ac**

#includeusing

namespace

std;

#define int long long

intn,m,i,j,len;

int w[5000000],f[5000000],g[5000000

];int rev[5000000],bit,ha=998244353

;inline

void getrev(int n)

int add(int x)

int jian(int x)

inline

int qpow(int a,intb);

return

ans;

}void fft(int *a,int n,int

x) }

int ni=qpow(n,ha-2

);

if(x)for(int i=0;iha;

}signed main()

view code

fft還有模意義下的版本ntt

只要把單位根變成模數的原根就行了,一般都是3,如998244353(1e9+7不是ntt模數)

如果要求沒有原根的多項式乘法,可以用crt把有原根的答案結合起來

再來道例題

ac**

#includeusing

namespace

std;

#define int long long

intn,m,i,j,len;

int w[2100000],f[2100000],g[2100000

];int rev[2100000],bit,ha=998244353

;inline

void getrev(int n)

int add(int x)

int jian(int x)

inline

int qpow(int a,intb);

return

ans;

}void fft(int *a,int n,int

x) }

int ni=qpow(n,ha-2

);

if(x)for(int i=0;iha;

}signed main()

view code

FFT學習筆記

fft可用於解決一些卷積問題。一般問題形式如下 c a b c i ij 0a i b i j 若把a,b看成兩個次數為n多項式 a x ni 0 a i xi,b x ni 0b i x i 原問題等於兩個多項式相乘,c的次數等於2n 1 乙個次數界為n的多項式a的點值表達為n個點值對所組成的集合...

FFT學習筆記

今天doggu講了,開始覺得這玩意好強啊 後來自己看的時候發現蠻zz wys表示 贊同 所以很多自己覺得遙不可及,一輩子都不可能學會的東西只要慢慢理解,理解好了再把他化為自己的語言,歸到自己的世界裡 就覺得不是很難了,甚至很簡單.當然開始並不是,從 好難啊 到 這麼簡單困大爺我這麼久,之前腦子抽了z...

FFT 學習筆記

f x sum limits a i x i x 0,f x 0 x 1,f x 1 x f x 首先我們要了解複數 即 i sqrt 乙個數有實部和虛部 即 a x y i x,y 原來的實數運算相當於在乙個一維數軸上進行移動,複數則是在二維平面上運動 一句話來說就是摸長相乘,幅角相加 c 中提供...