• COJ0702 数学(三)


    数学(三)
    难度级别:D; 运行时间限制:1800ms; 运行空间限制:262144KB; 代码长度限制:2000000B
    试题描述
    给出两个正整数a,b,求a*b。
    输入
    输入共两行,每行是一个正整数。
    输出
    输出共一行,为他们的乘积。
    输入示例
    2
    2
    输出示例
    4
    其他说明
    0<a,b<=10^200000

    经典问题,用FFT加速大整数乘法。

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=800010;
    const double PI=acos(-1.0);
    struct FFT {
        struct cox {
            double r,i;
            cox(double _r=0.0,double _i=0.0) {r=_r;i=_i;}
            cox operator + (const cox& b) {return cox(r+b.r,i+b.i);}
            cox operator - (const cox& b) {return cox(r-b.r,i-b.i);}
            cox operator * (const cox& b) {return cox(r*b.r-i*b.i,r*b.i+i*b.r);}
        }f[maxn];
        int len;
        void init(char* A,int L,int Len) {
            len=L;rep(i,0,Len-1) f[i]=cox(A[Len-i-1]-'0',0);
        }
        void fft(int tp) {
            int j=len>>1;
            rep(i,1,len-2) {
                if(i<j) swap(f[i],f[j]);int k=len>>1;
                while(j>=k) j-=k,k>>=1;j+=k;
            }
            double lm=-2*tp*PI;
            for(int i=2;i<=len;i<<=1) {
                cox wn(cos(lm/i),sin(lm/i));
                for(int j=0;j<len;j+=i) {
                    cox w(1,0);
                    for(int k=j;k<j+(i>>1);k++) {
                        cox u=f[k],v=w*f[k+(i>>1)];
                        f[k]=u+v;f[k+(i>>1)]=u-v;w=w*wn;
                    }
                }
            }
            if(tp<0) rep(i,0,len-1) f[i].r/=len;
        }
    }a,b;
    void mul(char* A,char* B,int L1,int L2,int& L,int* ans) {
        L=1;while(L<L1<<1||L<L2<<1) L<<=1;
        a.init(A,L,L1);b.init(B,L,L2);a.fft(1);b.fft(1);
        rep(i,0,L-1) a.f[i]=a.f[i]*b.f[i];
        a.fft(-1);rep(i,0,L-1) ans[i]=int(a.f[i].r+0.5);
    }
    char A[maxn],B[maxn];
    int ans[maxn];
    int main() {
        scanf("%s%s",A,B);
        int L1=strlen(A),L2=strlen(B),L;
        mul(A,B,L1,L2,L,ans);
        rep(i,0,L-2) {
            ans[i+1]+=ans[i]/10;
            ans[i]%=10;
        }
        while(L>1&&!ans[L-1]) L--;
        dwn(i,L-1,0) putchar(ans[i]+'0');
        return 0;
    }
    View Code
  • 相关阅读:
    关于视图的一些认识
    __autoload()尝试加载未定义的类
    php正则逆向引用与子模式分析
    常州day1p4
    Hello World
    Linux安装配置jdk
    使用http3访问服务
    后端访问sso后,如何返回前端vue页面(后端redirect跳转,vue代理,axios带参)
    linux常用命令
    使用nexus搭建npm私服
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4692443.html
Copyright © 2020-2023  润新知