zoukankan      html  css  js  c++  java
  • P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

    题目描述

    给出两个n位10进制整数x和y,你需要计算x*y。

    输入输出格式

    输入格式:

    第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。

    输出格式:

    输出一行,即x*y的结果。(注意判断前导0)

    输入输出样例

    输入样例#1: 复制
    1
    3
    4
    输出样例#1: 复制
    12

    说明

    数据范围:

    n<=60000

    来源:bzoj2179

    //problem: P1919 【模板】A*B Problem升级版(FFT快速傅里叶)
    
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int N=2e5+5;
    const double Pi=acos(-1);
    
    int n,m;
    int rev[N];
    char s[N];
    int bit,len=1;
    struct Complex
    {
        double x,y;
        Complex(double xx=0,double yy=0){x=xx,y=yy;}
        Complex operator + (const Complex &a)
        {
            return Complex(this->x + a.x,this->y + a.y);
        }
        Complex operator - (const Complex &a)
        {
            return Complex(this->x - a.x,this->y - a.y);
        }
        Complex operator * (const Complex &a)
        {
            return Complex(this->x * a.x - this->y * a.y, this->x * a.y + this->y * a.x);
        }
    }a[N],b[N];
    
    inline int read()
    {
        char c=getchar();int num=0;
        for(;!isdigit(c);c=getchar());
        return c^'0';
    }
    
    void fft(Complex *A,int type)
    {
        for(int i=0;i<len;++i)
            if(i<rev[i])
                swap(A[i],A[rev[i]]);
        for(int step=1;step<len;step<<=1)
        {
            Complex wn(cos(Pi/step),type*sin(Pi/step));
            for(int j=0;j<len;j+=step<<1)
            {
                Complex wnk(1,0);
                for(int k=j;k<step+j;++k)
                {
                    Complex x=A[k];
                    Complex y=wnk*A[k+step];
                    A[k]=x+y;
                    A[k+step]=x-y;
                    wnk=wnk*wn;
                }
            }
        }
    }
    
    int ans[N];
    int main()
    {
        scanf("%d",&n);
        for(int i=n-1;i>=0;--i)
            a[i].x=read();
        for(int i=n-1;i>=0;--i)
            b[i].x=read();
        while(len<=n*2)
            len<<=1,++bit;
        for(int i=0;i<len;++i)
            rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
        fft(a,1);
        fft(b,1);
        for(int i=0;i<=len;++i)
            a[i]=a[i]*b[i];
        fft(a,-1);
        int front=0,R=n<<1;
        for(;(int)(a[R].x/len+0.5)==0;--R);
        for(int i=0;i<=R;++i)
            ans[i]=(int)(a[i].x/len+0.5);
        for(int i=0;i<=R;++i)
        {
            if(ans[i]>=10)
            {
                ans[i+1]+=ans[i]/10;
                ans[i]%=10;
            }
        }
        if(ans[R+1])
            ++R;
        for(int i=R;i>=0;--i)
            printf("%d",ans[i]);
        return 0;
    }
    
    /*
    10 
    9789344841 
    4839019669 
    
    47370832232222677629
    */
  • 相关阅读:
    ionic platform add ios, Error:spawn EACCES
    OC中分类(Category)和扩展(Extension)
    JSON.stringify() 格式化 输出log
    JavaScript 闭包
    vue路由跳转到指定页面
    vue使用路由跳转到上一页
    vue子传父多个值
    vue里router-link标签设置动态路由的3个方法
    地址栏的路由输入不匹配时候,设置默认跳转页面(redirect)
    把router-link标签渲染成指定的标签
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8977504.html
Copyright © 2011-2022 走看看