[Template] A * B Problem (FFT Fast Fourier)

Title: given two 10-ary n-bit integers x and y, you need to calculate x * y. ($ N \ leq 60000 $)

analysis:

Multiplying two positive integers can be regarded as multiplying two polynomials,

E.g. $ 15 \ times 16 = 240 $,

Can be written $ (5 + x) * (6 + x) = 30 + 11x + x ^ 2 $, $ x = 10 $

Thus obtained polynomial $ A (x) $ and $ B (x) $, and can be determined FFT $ C (x) = A (x) B (x) $,

How to get the final result, we want $ x = 10 $ substituting it?

$ N $ is so big, not so large to traverse over the type of data can save enough, and secondly, this is not necessary.

$ X = 10 $ is $ C (x) $ has the equivalent of a decimal, we simulate what carry it.

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN = 4 * 60000 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while (c < '0' || c > '9') {if (c == '-')f = -1; c = getchar();}
    while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x * f;
}
const double Pi = acos(-1.0);
const double Eps = 1e-8;
double ccos[MAXN], ssin[MAXN];
struct complex {
    double x, y;
    complex (double xx = 0, double yy = 0) {x = xx, y = yy;}
} a[MAXN], b[MAXN];
complex operator + (complex a, complex b) { return complex(a.x + b.x , a.y + b.y);}
complex operator - (complex a, complex b) { return complex(a.x - b.x , a.y - b.y);}
complex operator * (complex a, complex b) { return complex(a.x * b.x - a.y * b.y , a.x * b.y + a.y * b.x);} //不懂的看复数的运算那部分
void fast_fast_tle(int limit, complex *a, int type) {
    if (limit == 1) return ; // only a constant term 
    Complex a1 [>> limit . 1 ], A2 [>> limit . 1 ];
     for ( int I = 0 ; I <limit; = I + 2 ) // The subscripts parity classification 
        a1 [I >> . 1 ] = A [I], A2 [I >> . 1 ] = A [I + . 1 ]; 
    fast_fast_tle (limit >> . 1 , A1, type); 
    fast_fast_tle (limit >> . 1 , A2, type) ; 
    Complex Wn of = Complex (CCOS [limit], type * SSIN [limit]), W = Complex ( . 1 , 0 );
    // Complex Complex Wn of = (COS (Pi * 2.0 / limit), SiN type * (2.0 * Pi / limit)), w = Complex (. 1, 0);
     // Wn of units of the root, w indicates power 
    for ( int = I 0 ; I <(>> limit . 1 ); I ++, Wn of W = W *) // W corresponds to the formula where K 
        a [I] A1 = [I] + W * A2 [I], 
               a [I + (limit >> . 1 )] A1 = [I] - A2 * W [I]; // use unit root nature, O (1) to give another portion 
} 

char S [MAXN];
 int RES [MAXN] ; 

int main () {
     int N = Read (); 
    Scanf ( " % S " , S);
    for (int i = 0; i < N; i++) a[i].x = s[N-1-i]-'0';
    scanf("%s", s);
    for (int i = 0; i < N; i++) b[i].x = s[N-1-i]-'0';

    //for(int i = 0;i < N;i++)  printf("%f ", a[i]);

    int limit = 1; while (limit <= 2*N) limit <<= 1;

    for(int i = 1;i <= limit;i++) 
    { 
        CCOS [I] = COS ( 2.0 * Pi / I); 
        SSIN [I] = SiN ( 2.0 * Pi / I); 
    } 

    fast_fast_tle (limit, A, . 1 ); 
    fast_fast_tle (limit, B, . 1 );
     / / 1 below indicates conversion to be performed what type
     @ 1 represents a point value from the coefficient becomes
     @ -1 indicates the point value becomes a factor
     // as to why this is, you can refer to the derivation of vectors c , 
    for ( int I = 0 ; I <= limit; I ++ ) 
        A [I] = A [I] * B [I]; 
    fast_fast_tle (limit, A, - . 1);

    for(int i = 0;i <= 2*N;i++)  res[i] = int(a[i].x/limit+0.5);

    int tmp = 0;    //进位
    for(int i = 0;i <= 2*N;i++)
    {
        res[i] += tmp;
        tmp = res[i] / 10;
        res[i] = res[i] % 10;
    }

    bool flag = false;
    for (int= I 2 * N; I> = 0 ; i-- ) 
    { 
       IF (RES [I]) = In Flag to true ;   // note processing leading 0 the stem, there is that 
        IF (In Flag) the printf ( " % D " , RES [I]);   // according to the formula of our down, here also divided by n- 
    }
     return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/lfri/p/11575465.html