本文是做者看不懂分治FFT以後開始娛樂一下本身寫的
看到一道題時候詢問了正解後,推出了一個奇怪的變換,發現這個很Transformation,我和正解推出來的奇怪的東西是同樣的,但仍是想寫一下思路。。。
(但願原題做者不要來D我啊)算法
考慮兩個卷積
\(C_{min(i,j)} = \sum_{i = 1}^{n}\sum_{j = 1}^{n} A_{i}B_{j}\)
\(C_{max(i,j)} = \sum_{i = 1}^{n}\sum_{j = 1}^{n} A_{i}B_{j}\)
普通的卷積,即咱們對下標進行加法操做後,將兩個數的乘積加到該下標,在這裏對下標的操做即便取min和取max數組
和暴力卷積同樣,這兩個卷積是能夠暴力\(n^2\)出解的,可是有沒有更優秀的作法呢函數
一種變換的出現,每每都是要把卷積變成點積,再用點積反解多項式的係數
例如FFT是插入函數值,利用兩個函數相乘的結果,某個x座標上的值即對應兩個函數值的乘積,再利用單位根的特殊性質將係數解出來
例如FWT的異或卷積,咱們要達成的成就就是\(tf(A)* tf(B) = tf(C)\),按最高位是0或1來分組,那麼就是\(C = (A_{0}*B_{0} + A_{1}*B_{1},A_{0} * B_{1} + A_{1} * B_{0})\),按照點積等於卷積後的答案,構造兩個乘法使得能夠獲得其中的每一項,即爲\((A_{0} + A_{1})(B_{0} + B_{1}) = A_{0}B_{0} + A_{0}B_{1} + A_{1}B_{0} + A_{1}B_{1}\)和\((A_{0} - A_{1})(B_{0} - B_{1}) = A_{0}B_{0} - A_{1}B_{0} - A_{0}B_{1} + A_{1}B_{1}\)
兩項相加除二即爲前半段,相減除二即爲後半段,兩個變換即爲\((tf(A_{0}) + tf(A_{1}),tf(A_{0}) - tf(A_{1}))\)複雜度\(O(n \log n)\)因爲\(n\)每每是\(2^{k}\)因此複雜度會被寫成\(O(2^{k}k)\)
因此咱們嘗試把這個卷積進行一樣的操做
(然而不少變換的方式都是不知道爲啥試出來的)優化
對於min卷積
咱們考慮變換\(C(i)\)爲\(SC(i)\),\(SC(i)\)表示\(x>=i\)的\(C(x)\)的和,\(SA(i)\)與\(SB(i)\)同理
而後便可發現\(SA(i) * SB(i) = SC(i)\),最後差分便可還原C數組,複雜度作到了\(O(n)\)spa
對於max卷積
咱們考慮變換\(C(i)\)爲\(SC(i)\),\(SC(i)\)表示\(x<=i\)的\(C(x)\)的和,\(SA(i)\)與\(SB(i)\)同理
而後便可發現\(SA(i) * SB(i) = SC(i)\),最後差分便可還原C數組,複雜度作到了\(O(n)\)code
咱們若是把一個數的標準分解(即質因數分解)做爲這個數的座標,例如
\(p_{1}^{k_{1}}p_{2}^{k_2}p_{3}^{k_{3}}...p_{n}^{k_{n}}\)
每一個數便可看作一個無窮維度裏,每個維度的下標爲該質因數的指數的一個座標orm
數組的多維前綴和即
\(f(n) = \sum_{d|n}a(d)\)
數組的多維後綴和即
\(f(n) = \sum_{n|d}a(d)\)
樸素的作法能夠達到\(O(n \log n)\),能夠過不少題目了,即對於一個數枚舉它的倍數(用調和級數算複雜度也是一個重要的技巧)io
咱們考慮如何將這個算法優化到\(O(n \log \log n)\)ast
咱們之前綴和爲例,從最小的質因子2開始,固定其餘全部質數的指數,開始考慮如下這個過程
1:a(1)
2:a(2)
3:a(3)
4:a(4)
5:a(5)
6:a(6)
7:a(7)
8:a(8)
9:a(9)
10:a(10)
初始化即每一個數組位置存儲對應的a(i)
第一次操做2,從後往前掃,咱們對每一個2的倍數進行累加,具體看下面
1:a(1)
2:a(2) a(1)
3:a(3)
4:a(4) a(2) a(1)
5:a(5)
6:a(6) a(3)
7:a(7)
8:a(8) a(4) a(2) a(1)
9:a(9)
10:a(10) a(5)form
第二次操做3
1:a(1)
2:a(2) a(1)
3:a(3) a(1)
4:a(4) a(2) a(1)
5:a(5)
6:a(6) a(3) a(2) a(1)
7:a(7)
8:a(8) a(4) a(2) a(1)
9:a(9) a(3) a(1)
10:a(10) a(5)
第三次操做5
1:a(1)
2:a(2) a(1)
3:a(3) a(1)
4:a(4) a(2) a(1)
5:a(5) a(1)
6:a(6) a(3) a(2) a(1)
7:a(7)
8:a(8) a(4) a(2) a(1)
9:a(9) a(3) a(1)
10:a(10) a(5) a(2) a(1)
第四次操做7
1:a(1)
2:a(2) a(1)
3:a(3) a(1)
4:a(4) a(2) a(1)
5:a(5) a(1)
6:a(6) a(3) a(2) a(1)
7:a(7) a(1)
8:a(8) a(4) a(2) a(1)
9:a(9) a(3) a(1)
10:a(10) a(5) a(2) a(1)
下一個質數是11,已經超出了範圍,因此操做完成了,至此,咱們已經完成了數組的多維前綴和
下面以相同的例子理解數組的多維後綴和
第一次操做2,從後往前掃
1:a(1) a(2) a(4) a(8)
2:a(2) a(4) a(8)
3:a(3) a(6)
4:a(4) a(8)
5:a(5) a(10)
6:a(6)
7:a(7)
8:a(8)
9:a(9)
10:a(10)
第二次操做3
1:a(1) a(2) a(4) a(8) a(3) a(6) a(9)
2:a(2) a(4) a(8) a(6)
3:a(3) a(6) a(9)
4:a(4) a(8)
5:a(5) a(10)
6:a(6)
7:a(7)
8:a(8)
9:a(9)
10:a(10)
第三次操做5
1:a(1) a(2) a(4) a(8) a(3) a(6) a(9) a(5) a(10)
2:a(2) a(4) a(8) a(6) a(10)
3:a(3) a(6) a(9)
4:a(4) a(8)
5:a(5) a(10)
6:a(6)
7:a(7)
8:a(8)
9:a(9)
10:a(10)
第四次操做7
1:a(1) a(2) a(4) a(8) a(3) a(6) a(9) a(5) a(10) a(7)
2:a(2) a(4) a(8) a(6) a(10)
3:a(3) a(6) a(9)
4:a(4) a(8)
5:a(5) a(10)
6:a(6)
7:a(7)
8:a(8)
9:a(9)
10:a(10)
因爲對每一個質數枚舉倍數(根據埃拉託斯特尼篩法的複雜度)是\(O(n \log \log n)\)的
因此求數組的標準分解意義下的多維前綴和,後綴和能夠作到\(O(n \log \log n)\)
因爲兩個數的GCD,即爲兩個數標準分解下的每一個質因數質數取min,即爲
\(p_{1}^{min(a_{1},b_{1}}p_{2}^{min(a_{2},b_{2})}...p_{k}^{min(a_{k},b_{k})}\)
相似min卷積,將數組處理成多維後綴和,即爲正變換
考慮如何將變換後的結果還原回去
sc數組中點積相乘的結果即爲
1:c(1) c(2) c(3) c(4) c(5) c(6) c(7) c(8) c(9) c(10)
2:c(2) c(4) c(6) c(8) c(10)
3:c(3) c(6) c(9)
4:c(4) c(8)
5:c(5) c(10)
6:c(6)
7:c(7)
8:c(8)
9:c(9)
10:c(10)
考慮如何將他們變換回去,咱們發現能夠採起咱們累加後綴和的步驟反序進行
即,從大到小枚舉質數,從前日後枚舉下標
第一次枚舉7
sc數組中點積相乘的結果即爲
1:c(1) c(2) c(3) c(4) c(5) c(6) c(8) c(9) c(10)
2:c(2) c(4) c(6) c(8) c(10)
3:c(3) c(6) c(9)
4:c(4) c(8)
5:c(5) c(10)
6:c(6)
7:c(7)
8:c(8)
9:c(9)
10:c(10)
第二次枚舉5
1:c(1) c(2) c(3) c(4) c(6) c(8) c(9)
2:c(2) c(4) c(6) c(8)
3:c(3) c(6) c(9)
4:c(4) c(8)
5:c(5) c(10)
6:c(6)
7:c(7)
8:c(8)
9:c(9)
10:c(10)
第三次枚舉3
1:c(1) c(2) c(4) c(8)
2:c(2) c(4) c(8)
3:c(3) c(6)
4:c(4) c(8)
5:c(5) c(10)
6:c(6)
7:c(7)
8:c(8)
9:c(9)
10:c(10)
第四次枚舉2
1:c(1)
2:c(2)
3:c(3)
4:c(4)
5:c(5)
6:c(6)
7:c(7)
8:c(8)
9:c(9)
10:c(10)
複雜度一樣爲\(O(n \log \log n)\),同時咱們能夠發現,數組標準分解意義下的多維後綴差分即便前綴和的逆步驟
同時,若是瞭解莫比烏斯反演,會列出等式
\(sc(n) = \sum_{n|d}c(d)\)
\(c(n) = \sum_{n|d}\mu(\frac{d}{n})sc(d)\)
即,該差分本質上是對\(sc(i)\)進行莫比烏斯反演,咱們又獲得了一種\(O(n \log \log n)\)求解莫比烏斯反演的辦法,而並不是\(O(n \log n)\)
咱們發現LCM即對兩個下標標準分解的每一個質因數取max,即
\(p_{1}^{max(a_{1},b_{1})}p_{2}^{max(a_{2},b_{2})}...p_{k}^{max(a_{k},b_{k})}\)
可是因爲LCM的性質,咱們下標的範圍會達到\(n^{2}\),比暴力好不到哪裏,因此討論起來就沒有太多意義
若是咱們強制限定長度在N範圍內,即變換成數組標準分解的多維前綴和,最後多維前綴差分還原回去,相似FGT
for(int i = 1 ; i <= tot ; ++i) { for(int j = N / prime[i] ; j >= 1 ; --j) { a[j] += a[j * prime[i]]; b[j] += b[j * prime[i]]; } } for(int i = 1 ; i <= n ; ++i) { c[i] = a[i] * b[i]; } for(int i = tot ; i >= 1 ; --i) { for(int j = 1 ; j <= N / prime[i] ; ++j) { c[j] -= c[j * prime[i]]; } }