Luo Gu P1919 A * B Problem upgraded version

My mom will finally \ (A * B \ problem \ ) friends ~ ~

Subject to the effect:

Give you two positive integers \ (A, b \) , seeking \ (a * b \)

Wherein \ (a, b \ le 10 ^ {1000000} \)

We just put the polynomial \ (A (x) = \ sum \ limits_ {i = 0} ^ {n-1} a_i * x_i \) a \ (X \) considered \ (10 \) Jiuhaola ~

Note that the input sequence and polynomial reverse order, remember to turn

Run \ (fft \) , then the coefficient obtained every high-precision multiply

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define eps (1e-8)
    inline int read()
    {
        int x=0;char ch,f=1;
        for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
        if(ch=='-') f=0,ch=getchar();
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    const int N=5e6+10;
    const double pi=acos(-1.0);
    int n,m;
    char aa[1000010],bb[1000010];
    int limit=1,len;
    int pos[N],ret[N];
    struct complex
    {
        double x,y;
        complex(double tx=0,double ty=0){x=tx,y=ty;}
        inline complex operator + (const complex t) const
        {
            return complex(x+t.x,y+t.y);
        }
        inline complex operator - (const complex t) const
        {
            return complex(x-t.x,y-t.y);
        }
        inline complex operator * (const complex t) const
        {
            return complex(x*t.x-y*t.y,x*t.y+y*t.x);
        }
    }a[N],b[N];
    inline void fft(complex *a,int inv)
    {
        for(int i=0;i<limit;++i)
            if(i<pos[i]) swap(a[i],a[pos[i]]);
        for(int mid=1;mid<limit;mid<<=1)
        {
            complex Wn(cos(pi/mid),inv*sin(pi/mid));
            for(int r=mid<<1,j=0;j<limit;j+=r)
            {
                complex w(1,0);
                for(int k=0;k<mid;++k,w=w*Wn)
                {
                    complex x=a[j+k],y=w*a[j+k+mid];
                    a[j+k]=x+y;
                    a[j+k+mid]=x-y;
                }
            }
        }
    }
    inline void main()
    {
        scanf("%s%s",aa,bb);
        n=strlen(aa),m=strlen(bb);
        for(int i=n-1;~i;--i) a[n-1-i].x=aa[i]-'0';
        for(int i=m-1;~i;--i) b[m-1-i].x=bb[i]-'0';
        while(limit<n+m) limit<<=1,++len;
        for(int i=0;i<limit;++i) pos[i]=(pos[i>>1]>>1)|((i&1)<<(len-1));
        fft(a,1);
        fft(b,1);
        for(int i=0;i<=limit;++i) a[i]=a[i]*b[i];
        fft(a,-1);
        
        for(int i=0;i<=limit;++i)
        {
            ret[i]+=a[i].x/limit+0.5;
            if(ret[i]>=10)
            {
                ret[i+1]+=ret[i]/10;
                ret[i]%=10;
                limit+=(i==limit);
            }
        }
        while(!ret[limit]&&limit) --limit;
        ++limit;
        while(--limit>=0) putchar('0'+ret[limit]);
    }
}
signed main()
{
    red::main();
    return 0;
}

Guess you like

Origin www.cnblogs.com/knife-rose/p/12037381.html