HDU 1402 A * B Problem Plus(FFT)

题意:求a*b

思路:直接FFT,被卡了很久,很难受,忘记考虑进位,还有数组开的太小导致一直wa

代码:

#include <bits/stdc++.h>
using namespace std;

namespace FFT {
    struct comp {
        double r, i;
        explicit comp(double r = 0.0, double i = 0.0) : r(r), i(i) {}
        inline friend comp operator +(comp a, comp b) {
            return comp(a.r + b.r, a.i + b.i);
        }
        inline friend comp operator -(comp a, comp b) {
            return comp(a.r - b.r, a.i - b.i);
        }
        inline friend comp operator *(comp a, comp b) {
            return comp(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r);
        }
        inline friend comp operator /(comp a, double b) {
            return comp(a.r / b, a.i / b);
        }
    };
    const double pi = acos(-1);
    const int N = 5e5 + 10;
    int rev[N];
    inline void fft(comp *p, int n, int idft) {
        for (int i = 0; i < n; i++)
            if (i < rev[i])
                std::swap(p[i], p[rev[i]]);
        for (int j = 1; j < n; j <<= 1) {
            static comp wn1, w, t0, t1;
            wn1 = comp(cos(pi / j), idft * sin(pi / j));
            for (int i = 0; i < n; i += j << 1) {
                w = comp(1, 0);
                for (int k = 0; k < j; k++) {
                    t0 = p[i + k];
                    t1 = w * p[i + j + k];
                    p[i + k] = t0 + t1;
                    p[i + j + k] = t0 - t1;
                    w = w * wn1;
                }
            }
        }
        if (idft == -1) {
            for (int i = 0; i < n; i++)
                p[i] = p[i] / n;
        }
    }
    template <typename T>
    inline T* fft_main(T *a, T *b, int n, int m) {
        static T res[N];
        static int nn, len;
        static comp aa[N], bb[N];
        len = 0;
        for (nn = 1; nn < m + n; nn <<= 1)
            len++;
        for (int i = 0; i < nn; i++) {
            aa[i] = comp(a[i], 0);
            bb[i] = comp(b[i], 0);
        }
        rev[0] = 0;
        for (int i = 1; i < nn; i++)
            rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1));
        fft(aa, nn, 1);
        fft(bb, nn, 1);
        for (int i = 0; i < nn; i++)
            aa[i] = aa[i] * bb[i];
        fft(aa, nn, -1);
        for (int i = 0; i < nn; i++)
            res[i] = aa[i].r + 0.5;
        return res;
    }
}

const int maxn=1000000+7;
int a[maxn],b[maxn],*ans;
char q[maxn];
int main()
{
    while(~scanf("%s",q)){
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        int len1,len2;
        int len=strlen(q);
        len1=len;
        for(int i=len-1,j=0;i>=0;i--,j++){
            a[j]=q[i]-'0';
        }
        scanf("%s",q);
        len=strlen(q);
        len2=len;
        for(int i=len-1,j=0;i>=0;i--,j++){
            b[j]=q[i]-'0';
        }
//        printf("len1==%d
",len1-1);
//        for(int i=0;i<len1;i++){
//            printf("%d",a[i]);
//        }
//        puts("");
//        printf("len2==%d
",len2-1);
//        for(int i=0;i<len2;i++){
//            printf("%d",b[i]);
//        }
//        puts("");
        ans=FFT::fft_main(a,b,len1,len2);
//        printf("test %d
",len1+len2-1);
//        printf("fuck %d %d %d
",ans[0],ans[1],ans[2]);
        for(int i=0;i<=len1+len2-3;i++){
            int as=ans[i]/10;
            ans[i]%=10;
            ans[i+1]+=as;
        }
        bool ok=false;
        for(int i=len1+len2-2;i>=0;i--){
            if(ans[i])printf("%d",ans[i]),ok=true;
            else if(ok||i==0)printf("0");
        }
        puts("");
    }
    return 0;
}
/*
21
121


1
123
*/
原文地址:https://www.cnblogs.com/lalalatianlalu/p/9405420.html