對於一種運算條件下,若\((w_n^1)^n = 1\),那麼\(w_n^1\)即\(n\)次單位根。
咱們令\(w_{n}^k = (w_{n}^1)^k\)。
單位根在複數意義下有三角表示:\(w_n^k = e^{\frac{2\pi k}{n}i} = cos(\frac{2\pi k}{n}) + sin(\frac{2\pi k}{n})i\)。
在模\(p\)意義下,因爲原根\(g\)知足\(g^{p-1} \equiv 1(mod\ p)\),因此能夠令\(w_{p}^1 = g^{\frac{p-1}{n}}\)。
複數運算的幾何意義:模長相乘,轉角相加。
根據複數乘法的幾何意義,顯然有:算法
這幾個性質後面都會用到。性能優化
咱們有式子:\(\frac{1}{n}\sum_{i=0}^{n - 1} (w_{n}^k)^i = [n|k]\),證實其實不難。
若\(n|k\),那麼\(w_n^k = w_{n}^0 = 1\),因此\(\sum_{i=0}^{n-1} (w_n^k)^i = n\)。
不然,\(\sum_{i=0}^{n-1} (w_n^k)^i = \frac{1-(w_{n}^{k})^n}{1 - w_{n}^k} = \frac{1 - w_n^0}{1 - w_n^k} = 0\)。
證畢。
能夠化簡大量包含形如\(\sum_i[d|i] F(i)\)的式子的計算。函數
咱們用\(n\)個點能夠表示出\(n-1\)次多項式,稱這種表示爲點值表示法。
點值表示法的多項式乘法顯然爲\(O(n)\),即\((x,y_1)*(x,y_2) = (x,y_1y_2)\)。
點值表示法轉系數表示法的傳統作法爲拉格朗日差值,複雜度\(O(n^2)\)。
傅里葉提出,經過帶入單位根,優化這個過程。
對於一個\(n-1\)次多項式\(A(x) = \sum_{i=0}^{n-1} a_i x^i\),考慮帶入\(x_k = w_{n}^k\)來作出點值表示,其中\(k\in[0,n)\)。
咱們設獲得的點值表示爲\(A(x):\{(w_n^k,y_k)|k\in [0,n)\}\) ,令\(B(x) = \sum_{i=0}^{n-1} y_i x^i\)。
把\(w_{n}^{k}\)的倒數分別帶入\(B(x)\)中:
\(B(w_n^{-k}) = \sum_{i=0}^{n-1} y_i w_n^{-ki} = \sum_{i=0}^{n-1} (\sum_{j=0}^{n-1} a_j w_n^{ij})w_n^{-ki}\)
\(B(w_n^{-k}) = \sum_{j=0}^{n-1} \sum_{i=0}^{n-1} a_j w_n^{(j-k)i}\),後面一坨就是單位根反演的變形。
\(B(w_n^{-k}) = \sum_{j=0}^{n-1} a_j (\sum_{i=0}^{n-1} w_n^{(j-k)i}) = k_j n\)。
因此\(a_k = \frac{B(w_n^{-k})}{n}\),爽!
能夠發現咱們不須要拉格朗日差值了,帶入單位根倒數得點值表示,而後除\(n\)就是每一項的係數了。
總結一下,咱們獲得了這樣的東西:
\(f_i = \sum_{j=0}^{n-1} w_n^j g_j\) --------------------> \(g_i = \frac{1}{n}\sum_{j=0}^{n-1} w_{n}^{-j} f_j\)。性能
考慮利用離散傅里葉變換,實現快速多項式乘法。
咱們假設求長度爲\(n\)的多項式的離散傅里葉變換,設\(d|n\)。
考慮求\(A(x) = \sum_{i=0}^{n-1} a_i x^i\)帶入\(w_n^{0,1...n-1}\)的點值表示結果,咱們按照模\(d\)剩餘類分類。
設\(A_r(x) = \sum_{i=0}^{\frac{n}{d} - 1} a_{id+ r} x^i\),假設咱們已經求得了它們帶入\(w_{\frac{n}{d}}^{0,1,...\frac{n}{d}-1}\)的點值表示結果。
那麼\(A(w_{n}^k) = \sum_{r=0}^{d-1} (w_{n}^{kr}) A_r((w_{n}^k)^d) = \sum_{r=0}^{d-1} (w_n^{kr\% n}) A_r(w_{\frac{n}{d}}^k)\)。
因此貌似分治就好了......
通常使用時,咱們把\(n\)補全爲\(2^t\),這樣\(d\)恆等於\(2\),每次折半分治便可。
關於非遞歸\(FFT\):
預處理每一個點分治若干次後到達的實際位置,而後從底向上還原(每次合併都是一段區間)。
快速數論變換(NTT)的原理與快速傅里葉變換(FFT)沒有任何區別,因此就不寫了。優化
當多項式乘法在指數模\(n\)意義進行,咱們乘其爲指數模\(n\)意義下的循環卷積。
而單位根有很好的性質:\(w_{n}^k = w_{n}^{k\% n}\) 。
咱們假設可以求出帶入\(w_n^{0,1,2...,n-1}\)後多項式的值,那麼\(Idft\)就可以求出原多項式的每一項係數。
一類特殊循環卷積:
考慮對於長度爲\(n\)的多項式\(A(x)\),\(B(x)\),求:
\(C(x):\ C_k = \sum_{i=0}^{n-1} \sum_{j=0}^{n-1}[(i+j)\%n=k] a_ib_j\)。
一個很是有趣的結論:
求得\(A(x)\)、\(B(x)\)的離散傅里葉變換的點值,那麼\(C(x)\)的點值表示就爲\(A(x)\)點值與\(B(x)\)點值的積。
即若你要求\(A(x)^m\),那麼只須要求\(A(x)\)的傅里葉變換點值,把點值\(m\)次方後再還原回去便可。
所謂傅里葉變換點值就是指帶入\(w_{n}^{0,1...,n - 1}\)獲得的點值 。
咱們來證實一下,其實暴力帶入驗證便可。
\(C(w_n^k) = A(w_n^k) B(w_n^k) = (\sum_{i=0}^{n-1} a_i w_n^{ki})(\sum_{j=0}^{n-1} b_j w_{n}^{kj})\)
\(C(w_n^k) = \sum_{i=0}^{n-1} \sum_{j=0}^{n-1} a_ib_j w^{k(i+j)}_n = \sum_{r=0}^{n-1} \sum_{i=0}^{n-1} \sum_{j=0}^{n-1}[(i+j)\%n=r] a_ib_j w_n^{k}\)
恰好就是循環卷積要求的東西,證畢。ui
嘿嘿嘿......見下面。spa
問題就是求\(B(x)^C\)在指數模\(n\)意義下的循環卷積,同時模數爲\(n+1\),多項式長度爲\(n\)。
咱們在上面已經討論過這種循環卷積的處理方式了。
因此只須要求\(B(x)\)帶入\(w_{n}^{0,1...n-1}\)的點值表示,而後\(C\)次方後再\(Idft\)回去。
咱們須要支持快速\(dft\),而咱們已知\(n\)可以分解爲\(2^{k_1}3^{k_2}5^{k_3} 7^{k_4}\)。
那麼考慮分治\(dft\),相似\(fft\)每次把多項式分紅若干份,而後自底向上合併便可。
因爲每次分紅的份數不超過\(7\),因此合併的複雜度顯然是正確的。
能夠預先搜出每一個點在分治\(dft\)的過程當中最後到了哪一個位置,這樣就能夠非遞歸實現算法了。遞歸
對於一棵生成樹,設其邊權爲\(\sum_{e\in E} val_e\),那麼\(Ans = \sum_E [k|\sum_{e\in E} val_e]\)。
單位根反演有:\(Ans = \frac{1}{k}\sum_E \sum_{j=0}^{k-1} (w_k^{\sum_{e\in E} val_e})^j = \frac{1}{k} \sum_{j=0}^{k-1} \sum_E \prod_{e\in E} (w_k^j)^{val_e}\)。
後面一坨是咱們熟悉的變元矩陣樹定理,因此\(\sum_E \prod_{e\in E} (w_k^j)^{val_e}\)直接用矩陣樹定理算便可。io
依舊考慮變元矩陣樹定理,考慮把邊權相加變爲邊權相乘。
定義每條邊\(e\)的生成函數\((1 + x^{val_e})\),那麼一個合法邊集能夠看作在指數模\(k\)意義下的循環卷積。
考慮令\(x = w_{k}^{0,1...k-1}\),那麼帶入\(w_k^j\)作矩陣樹定理就可以獲得\(A(w_k^{j})\)。
而咱們的最終目標是求\(A(x)\)中的係數\(a_0\),因此再\(Idft\)便可。class
考慮組合意義,不難發現\(ans_t\)就是\((1+x)^n\)在指數模\(k\)意義下的循環卷積第\(t\)項的係數。
暴力帶入\(w_k^{0,1...,k-1}\),得點值表示後再\(Idft\)便可。
考慮暴力單位根反演,\(Ans_t = \sum_{i=0}^{n} \binom{n}{i} [k|i-t] = \frac{1}{k}\sum_{i=0}^{n} \binom{n}{i} \sum_{j=0}^{k-1} (w_{k}^{i-t})^j\)。
因此\(Ans_t = \frac{1}{k} \sum_{j=0}^{k-1} (w_k^{-t})^j \sum_{i=0}^n \binom{n}{i} (w_{k}^i)^j = \frac{1}{k} \sum_{j=0}^{k-1} (w_k^{-t})^j (1 + w_k^j)^n\) 。
不難發現這是一個\(Idft\)形式。
咱們把\((1+w_k^j)^n\)看作\(A(w_k^j)\)(指數模\(k\)意義下的循環卷積),即\((1+w_k^j)^n = A(w_k^j) = y_j\) 。
那麼\(Ans_t = B(w_k^{-t}) = \frac{1}{k} \sum_{j=0}^{k-1} y_j (w_k^{-t}) = \frac{1}{k} (a_t k) = a_t\)。
因此\(Ans_t\)等於\(A(x) = (1 + x)^n\)這個循環卷積的第\(t\)項係數,與咱們組合意義所得的內容一致。