FFT簡明指南

2022-08-17 11:18:18 字數 2219 閱讀 1912

fft是用來計算多項式卷積的東西。

多項式卷積: \(c=a\ast b\) ,即 \(c_k=\sum_ a_i\times b_j\) 。(假設下標範圍 \(0-n\) )

直接按照定義做是 \(o(n^2)\) 的,但是fft可以做到 \(nlog(n)\) 。

考慮乙個 \(n\) 次多項式,取 \(n\) 個不同的 \(x\) 代入會得到 \(n\) 個 \(y\) ,然後發現由於我們可以解方程,因此只要不是無解、多解,我們可以說,乙個 \(n\) 次多項式和乙個(有 \(n\) 個點的集合一一對應)。

對於多項式 \(a=\sum_^a_i\times x^i\) ,定義其在 \(x=x_0\) 處的點值為 \(a(x_0)=\sum_^a_i\times x_0^i\) 。

多項式係數表示:對於 \(a=\sum_^ a_i\times x^i\) ,係數表示為 \(a=\\}\) 。

多項式點值表示: \(a=\,y_)\}\) 。如果 \(x\) 的取值確定的情況下,顯然也可以寫成 \(a=\\}\) 。這樣的話,多項式的係數、點值表示都可以寫成乙個向量vector的形式了。

點值表示中,若a與b \(x\) 的取值相同,它們相乘只需要把 \(x\) 對應的 \(y\) 分別相乘即可。

n次單位根(其實n次單位根只應該有1個,但是為了方便這裡就當作有n個):方程 \(x^n=1\) 的n個複數根,分別稱為 \(w_n^0,w_n^1,w_n^2,...,w_n^\) ,其中 \(w_n^0=1\) 。簡記為 \(w_\) 。不引起歧義的情況下,我會寫成 \(w_0\) 。同時,在這裡,n應該是2的冪次(原因後文會講)。

主要用到的n次單位根的性質: \(w_^k=w_,w_=w_,w_}=-w_\) 。

dft,就是把乙個長度為 \(n\) 次的向量(多項式係數表示)代入 \(n\) 次單位根,從而轉換為另乙個向量(多項式點值表示)。而idft,是把以上點值表示轉換為係數表示。它們的複雜度都是 \(o(n\log n)\) 。

好,假設我們現在需要把乙個長為 \(2^=n\) 的多項式 \(a=\sum_^a_i\times x^i\) 轉換為點值表示(係數表示和係數表示向量被認為是相同的)。

我們先把它分成兩部分:

\[a=\sum_^-1}a_\times x^+\sum_^-1}a_\times x^。

\]構造兩個新的多項式,其係數表示的向量分別為:

\[a_1=\\}\\

a_2=\\}

\]把這兩個多項式分別變成點值表示(相當於遞迴向下做):

\[a_1=\,0},a_0),(w_,1},a_2),...,(w_,\frac-1},a_)\}\\

a_2=\,0},a_1),(w_,1},a_2),...,(w_,\frac-1},a_)\}

\]然後考慮我們需要的是a的點值表示。列舉每乙個 \(n\) 階單位根,我們需要知道a代入 \(w_n^i\) 的值。然後再看一下第乙個公式

\[a=\sum_^-1}a_\times x^+\sum_^-1}a_\times x^。

\]又因為有 \((w_n^1)^2=w_n^2=w_}^1\) ,所以代入 \(w_n^i\) 後,點值就是a1在 \(w_}^i\) 處的點值加上 \(w_n^i\times a_2[w_}^i]\) 。

inline void fft(complex *a,int len,int fl);
dft中,a開始存係數,後來存\(a[w_i]\)。

基本**:

inline void fft(complex *a,int len,int fl)

fft(a1, len / 2, fl);

fft(a2, len / 2, fl);

complex w = init(len, fl), cur = (complex)1;

rep(i, 0, len)

}

如果把最終的數字轉換的結果放出來,就是這樣的:

int tmp;

inline void fft(complex *a,int len,int fl)

// reverse

complex w, step, tmp;

for (i = 1; i < len; i <<= 1)}}

}

(上面的加減可能需要理解)

如上,但是把所有的 \(n\) 次單位復根換成 \(\pm 3^\mod\) 。

git 簡明指南

助你入門 git 的簡明指南,木有高深內容 建立新資料夾,開啟,然後執行 git init 以建立新的 git 倉庫。執行如下命令以建立乙個本地倉庫的轉殖版本 git clone path to repository 如果是遠端伺服器上的倉庫,你的命令會是這個樣子 git clone usernam...

git 簡明指南

建立新倉庫 建立新資料夾,開啟,然後執行 git init 以建立新的 git 倉庫。檢出倉庫 執行如下命令以建立乙個本地倉庫的轉殖版本 git clone path to repository 如果是遠端伺服器上的倉庫,你的命令會是這個樣子 git clone username host path...

git 簡明指南

助你入門 git 的簡明指南,木有高深內容 tweet 感謝 tfnico,fhd 和 namics 其他語言 english,deutsch,espa ol,fran ais,indonesian,italiano,nederlands,polski,portugu s,t rk e,日本語,vi...