luogu P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

模板

做多项式乘法,进位
没了

#include<cmath> 
#include<cstdio> 
#include<cstring> 
#include<algorithm> 
#define pi acos(-1.0) 
inline int read() { 
    int x = 0,f = 1;
    char c = getchar(); 
    while(c < '0' || c > '9')c = getchar(); 
    while(c <= '9' && c >= '0')x = x * 10 + c - '0',c = getchar(); 
    return x * f;
} 
const int maxn = 400007; 
struct cp { 
    double x,y; 
    cp (double a = 0,double b = 0): x(a),y(b) {}; 
} A[maxn],B[maxn]; 
cp operator + (cp a,cp b) { return cp(a.x + b.x,a.y + b.y);} 
cp operator - (cp a,cp b) { return cp(a.x - b.x,a.y - b.y);} 
cp operator * (cp a,cp b) { return cp(a.x * b.x - a.y * b.y,a.x * b.y + a.y * b.x); } 
void fft(cp *a,int n, int type) { 
    for(int i = 0,j = 0;i < n;++ i)  { 
        if(i < j) std::swap(a[i],a[j]); 
            for(int k = n >> 1;(j ^= k) < k;k >>= 1);       
    } 
    for(int m = 2;m <= n;m <<= 1) { 
        cp w1 = cp(cos(2 * pi / m),type * sin(2 * pi / m)); 
        for(int i = 0;i < n;i += m) { 
            cp w = cp(1.0,0); 
            for(int k = 0;k < (m >> 1);++ k) { 
                cp t = w * a[i + k + (m >> 1)],u = a[i + k];
                a[i + k] = u + t; 
                a[i + k + (m >> 1)] = u - t; 
                w = w * w1; 
            } 
        }
    }   
} 
int c[maxn]; 
char s1[maxn],s2[maxn]; 
int main() { 
    int n = read(); --n; 
    scanf("%s%s",s1,s2); 
    for(int i  = 0;i <= n;++ i) A[i].x = s1[n - i] - '0',B[i].x = s2[n -i] - '0'; 
    int tmp = n; 
    //printf("%d\n",n); 
    for(n = 1;n <= tmp * 2;n <<= 1); 
    //printf("%d\n",n); 
    fft(A,n,1); 
    fft(B,n,1); 
    /*for(int i = 0;i <= n;++ i)  {
        printf("%lf\n",A[i].x);      
    } */
    for(int i = 0;i <= n;++ i) A[i] = A[i] * B[i]; 
    fft(A,n,-1); 
    for(int i = 0;i <= n;++ i) c[i] = int(A[i].x / n + 0.5); 
    for(int i = 0;i <= n;++ i)  
        if(c[i] > 10) { 
            //printf("%d\n",c[i]); 
            c[i + 1] += c[i] / 10,c[i] %= 10; 
            if(i + 1 > n) n ++; 
        } 
    for(int i = n;i >= 0;i --)  
        if(!c[i]) n--;else break; 
    for(int i = n;i >= 0;i --) printf("%d",c[i]); 
    puts("");
    return 0; 
} 
 

猜你喜欢

转载自www.cnblogs.com/sssy/p/9192085.html