作用:把一个多项式 $f(x)$ 转化成点值表示 $\{(x_0,f(x_0)),(x_1,f(x_1)),\ldots,(x_n,f(x_n))\}$ 的形式。
推导过程:
记 $\omega_k^n=e^{\frac{2k\pi}{n}}$
若 $f(x)=\sum_{i=0}^{n-1}a_ix^i$
将 $f(x)$ 按奇偶次拆开 $f(x)=(a_0+a_2x^2+\ldots+a_{n-2}x^{n-2})+x(a_1+a_3x^2+\ldots+a_{n-1}x^{n-2})=f_1(x^2)+xf_2(x^2)$
其中 $f_1(x)=a_0+a_2x+a_4x^4+\ldots+a_{n-2}x^{\frac{n}{2}-1},f2(x)=a_1+a_3x+\ldots+a_{n-1}x^{\frac{n}{2}-1}$
代入 ${\omega}_k^n$ ,得 $f({\omega}_n^k)=f_1({\omega}_n^{2k})+{\omega}_n^kf_2({\omega}_n^{2k})=f_1({\omega}_{\frac{n}{2}}^k)+{\omega}_n^kf_2({\omega}_{\frac{n}{2}}^k)$
同理 $f({\omega}_n^{k+\frac{n}{2}})=f_1({\omega}_{\frac{n}{2}}^k)-{\omega}_n^kf_2({\omega}_{\frac{n}{2}}^k)$
到这里,可以对这个函数进行分治了,时间复杂度 $O(nlogn)$
代码:
#include<complex> using namespace std; const double Pi=acos(-1); void dft(complex<double> *f,int len) { if (len==1)return ;// complex<double> *fl=f,*fr=f+len/2; for (int k=0;k<len;k++)sav[k]=f[k]; for (int k=0;k<len/2;k++) {fl[k]=sav[k<<1];fr[k]=sav[k<<1|1];} dft(fl,len/2); dft(fr,len/2); complex<double> e(cos(2*Pi/len),sin(2*Pi/len)) complex<double> i(1,0); for (int k=0;k<len/2;k++){ sav[k]=fl[k]+i*fr[k];//(1) sav[k+len/2]=fl[k]-i*fr[k];//(2) i=e*i; }for (int k=0;k<len;k++)f[k]=sav[k]; }