• FFT模板 大整数乘法


    //FFT 大整数乘法
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    
    const int N = 500005;
    const double pi = acos(-1.0);
    
    char s1[N],s2[N];
    int len,res[N];
    
    struct Complex
    {
        double r,i;
        Complex(double r=0,double i=0):r(r),i(i) {};
        Complex operator+(const Complex &rhs)
        {
            return Complex(r + rhs.r,i + rhs.i);
        }
        Complex operator-(const Complex &rhs)
        {
            return Complex(r - rhs.r,i - rhs.i);
        }
        Complex operator*(const Complex &rhs)
        {
            return Complex(r*rhs.r - i*rhs.i,i*rhs.r + r*rhs.i);
        }
    } va[N],vb[N];
    
    void rader(Complex F[],int len) //len = 2^M,reverse F[i] with  F[j] j为i二进制反转
    {
        int j = len >> 1;
        for(int i = 1;i < len - 1;++i)
        {
            if(i < j) swap(F[i],F[j]);  // reverse
            int k = len>>1; 
            while(j>=k)
            {
                j -= k;
                k >>= 1;
            }
            if(j < k) j += k;
        }
    }
    
    void FFT(Complex F[],int len,int t)
    {
        rader(F,len);
        for(int h=2;h<=len;h<<=1)
        {
            Complex wn(cos(-t*2*pi/h),sin(-t*2*pi/h));
            for(int j=0;j<len;j+=h)
            {
                Complex E(1,0); //旋转因子
                for(int k=j;k<j+h/2;++k)
                {
                    Complex u = F[k];
                    Complex v = E*F[k+h/2];
                    F[k] = u+v;
                    F[k+h/2] = u-v;
                    E=E*wn;
                }
            }
        }
        if(t==-1)   //IDFT
            for(int i=0;i<len;++i)
                F[i].r/=len;
    }
    
    void Conv(Complex a[],Complex b[],int len) //求卷积
    {
        FFT(a,len,1);
        FFT(b,len,1);
        for(int i=0;i<len;++i) a[i] = a[i]*b[i]; 
        FFT(a,len,-1);
    }
    
    void init(char *s1,char *s2)
    {
        int n1 = strlen(s1),n2 = strlen(s2);
        len = 1;
        while(len < 2*n1 || len < 2*n2) len <<= 1;
        int i;
        for(i=0;i<n1;++i)
        {
            va[i].r = s1[n1-i-1]-'0';
            va[i].i = 0;
        }
        while(i<len)
        {
            va[i].r = va[i].i = 0;
            ++i;
        }
        for(i=0;i<n2;++i)
        {
            vb[i].r = s2[n2-i-1]-'0';
            vb[i].i = 0;
        }
        while(i<len)
        {
            vb[i].r = vb[i].i = 0;
            ++i;
        }
    }
    
    void gao()
    {
        Conv(va,vb,len);
        memset(res,0,sizeof res);
        for(int i=0;i<len;++i)
        {
            res[i]=va[i].r + 0.5;
        }
        for(int i=0;i<len;++i)
        {
            res[i+1]+=res[i]/10;
            res[i]%=10;
        }
        int high = 0;
        for(int i=len-1;i>=0;--i)   
        {
            if(res[i])  
            {
                high = i;
                break;
            }
        }
        for(int i=high;i>=0;--i) putchar('0'+res[i]);
        puts("");
    }
    
    
    int main()
    {
        while(scanf("%s %s",s1,s2)==2)
        {
            init(s1,s2);
            gao();
        }
        return 0;
    }
  • 相关阅读:
    NGINX_深度优化实践
    NFS服务端___NFS客户端
    NFS 批量管理 分发
    MYSQL---数据备份与还原
    MYSQL---建立字符集数据库
    MYSQL---基于mysql多实例数据库创建主从复制
    MYSQL---关于MYSQL优化
    bug记录-left jion连接后不是一对一情况时,记得去重
    bug记录-不等于某个值,查询后注意不包括为空的情况(由于NULL不能直接用算术运算符进行比较值。要想把为NULL 的那行也查询出来的话,只能使用IS NULL)
    bug记录-sqljion连接 like
  • 原文地址:https://www.cnblogs.com/orion7/p/7283508.html
Copyright © 2020-2023  润新知