前言
最近寫了一道題[HNOI2017]禮物,要用一下FFT,然而上一次寫FFT已經是8months之前了。。。
所以來複習一下
然後就溫故而知新了
於是來博客寫一下感悟
內容一:泰勒展開
它就是這個東西:(將f(x)在x0處進行泰勒展開)
它的本質就是從點x0開始逼近函數f(x)
這個有什麼用呢?
它可以定義複數的exp
我們只需要把x帶成z=a+b*i就可以計算複數的exp
同樣sinx,cosx都可以進行泰勒展開
內容二:歐拉公式
如果我們把z帶爲ib
我們就會發現一個神奇(明顯)的現象:所有的項的係數是四個一循環(廢話,i^x的最小循環節不就是4嘛)
如果我們把實數分爲一組,虛數分爲一組:
稍有常識的人就能看出,經常被泰勒展開的人就能看出,經常用泰勒展開的人就知道
於是我們就發現了歐拉公式:
所以複數的exp就可以表示爲:
其實e^a就是這個新複數e^(a+ib)的模長,b就是就是這個新複數與x軸的夾角
內容三:複數
讓我們再來理解一下複數
我們在複平面上的一個複數z=a+ib,我們也可以把它表示爲另一個複數的exp (有點極座標的思想)
那我們再來理解一下複數的乘法,設z1=e^(a+ib),z2=e^(c+id)
那麼:
把後面那一個帶入歐拉公式,得:
因爲原來複數的長度分別爲e^a和e^c,夾角分別爲b和d
而新複數的長度爲e^a*e^c,夾角爲b+d
於是我們就通過歐拉公式得到了複數乘法的幾何意義:
兩個複數相乘,所得複數模長爲這兩個複數的模長乘積,夾角爲這兩個複數的夾角之和
感覺棒棒噠
內容四:單位根
單位根就是滿足x^n=1的所有複數解,記爲
現在有了複數乘法的幾何意義,我們就明白了爲什麼n次單位根是複平面單位圓的n等分點了
單位根的性質我就不再贅述了:https://blog.csdn.net/C20180602_csq/article/details/85015587
有了以上的性質,我們就可以比較輕鬆的看懂FFT的前置知識了
內容五:多項式基礎知識(不贅述見https://blog.csdn.net/C20180602_csq/article/details/85015587)
內容六:FFT的分治思想
首先我們來考慮如何求f(x)在x取的值(假設n是2的冪)
首先單位根有一個很好的性質:(顯然)
如果我們把k取2:
再把每一個值乘以
那麼我們就可以把變成(不乘)和(乘以)
這個有什麼用呢?
它告訴我們:
如果想要求出f(x)在處的取值
那麼我們可以先求出f(x)在上的取值,再通過加減乘除得到f(x)在的取值
但是因爲在2n等分圓上對應的點是(不乘)和(乘以)
如果直接帶入的話會導致係數不對:
帶入的是一個n次多項式,係數分別爲:
帶入的也是一個n次多項式,係數分別爲:
所以我們應該把分別帶入兩個不同的多項式求值
說白了一句話:係數與帶入點值同時分治
看一個例子就明白了
多項式
需要帶入的點值
我們把f(x)按ai下表的奇偶來分治
把帶入點值分治爲和,分別對f0(x)和f1(x)求值
但是因爲 ,
所以我們只需要求f0(x)和f1(x)在的值就可以了
然後我們就可以通過暴算得到下面等式:
(把左邊的提出來就好了)
讀者自己驗證吧,筆者實在打不動了。。。。
其實FFT的分治思想的確挺巧妙的,主要是單位複數根的性質太好了
(以後用fft就不要把它當成黑盒算法了)