Problem:
Known a[], b[], seeking c[], so that:
Defines c as a/b convolution, such as polynomial multiplication.
The naïve approach is to follow the definition of enumerations I and J, but this time complexity is O (N2).
Can the complexity of time be lowered?
Point value notation:
We regard a,b,c as an expression.
That
A (x) =a0 + a1* x + a2 * x2 + ...
Will a={(X1,a (x1)), (X2,a (x2)), (X3,a (x3)) ...} A point value notation called a.
It is easy to multiply the polynomial by using the dot-value notation: the corresponding items are multiplied.
So, how to convert a and B into point value notation, and then convert C back to the coefficient notation (that is, the original presentation method)?
If you take n points and calculate by definition, then O (N2).
This will use the fast Fourier transform.
Fast Fourier transforms:
Since any n points are taken, it is too slow to calculate by definition, so we need to find some special points.
We use N-N-units complex roots (1 of the N-root, involving complex numbers, 1 of the square root more than 1 and-1) to calculate:
The n-root of 1 is, where I is the imaginary unit.
We define that the WN = e^ (2∏i) is the primary n-th unit root, then all n units of the plural root are its sub-sides.
If we ask for a (WNK), we should adopt the idea of divided treatment.
We separate the parity coefficients (assuming n is an even number first), which is defined
A1 (x) =a0 + a2* x + a4 * x2 + ...
A2 (x) =A1 + a3* x + a5 * x2 + ...
So a (x) =a1 (x2) + xA2 (x2).
To calculate a (Wnk) =a1 ((WNK) 2) + wnkA2 ((WNK) 2),
Need to use (WNK) 2 = wn/2k mod (N/2) (card).
So a (Wnk) =a1 (wn/2k mod (N/2)) + wnkA2 (wn/2k mod (N/2))
We find that a1,a2 are all N/2 and only need to calculate the value of wn/2k, then this is the same as the beginning of the problem, can be divided.
The boundary is also very easy: n=1 when the A1 itself is the value.
Merge solution.
A (Wnk) =a1 (wn/2k mod (N/2)) + wnkA2 (wn/2k mod (N/2))
Then a (WNK) and a (WNK+N/2) can be counted together (0<=K<N/2):
Set U = A1 (wn/2k), t = wnkA2 (wn/2k),
So a (Wnk) = U + t
A (WNK+N/2) = A1 (wn/2k) + Wnk + n/2 A2 (wn/2k)
= A1 (wn/2k) + wnk WNN/2 A2 (wn/2k)
= A1 (wn/2k)-Wnk A2 (wn/2k)
= U-t
So we can figure out the point value notation for a.
A problem: divide and conquer requirements N is a power of 2, not how to do? Fill 0 until it is a power of 2.
The remaining question: How to convert C back to the coefficient notation.
Fast Fourier inverse transformation:
Let's do a fast Fourier transform for C, just asking for WNN, wnn-1, ..., wn1 values instead of Wn0, Wn1, ..., wnn-1 values, and finally each item divided by N.
The card.
1 voidRader (complex y[],intlen)2 {3 inti,j,k;4 for(i =1, j = len/2; I < len-1; i++)5 {6 if(I <j) Swap (Y[i],y[j]);7K = len/2;8 while(J >=k)9 {TenJ-=K; OneK/=2; A } - if(J < k) J + =K; - } the } - voidFFT (complex y[],intLenintOn//on = 1 Fast fourier transform, on = 0 Fast fourier inverse transformation - { - rader (y,len); + for(inth =2; h <= len;h <<=1) - { +Complex WN (cos (-on*2*pi/h), sin (-on*2*pi/h)); //e^ki = Cosk + Isink A for(intj =0; J < Len;j + =h) at { -Complex W (1,0); - for(intK = J;k < j+h/2; k++) - { -Complex U =Y[k]; -Complex T = w*y[k+h/2]; inY[k] = u+T; -y[k+h/2] = uT; toW = w*WN; + } - } the } * if(On =-1) $ for(inti =0; I < len;i++)Panax NotoginsengY[I].R/=Len; -}
a //plural implementation slightly
fft--Fast Fourier transform