zoukankan      html  css  js  c++  java
  • 【HDU 1402】A * B Problem Plus(FFT)

    Problem Description


    Calculate A * B.

    Input


    Each line will contain two integers A and B. Process to end of file.
    Note: the length of each integer will not exceed 50000.

    Output


    For each case, output A * B in one line.

    Sample Input

    1
    2
    1000
    2
    

    Sample Output

    2
    2000
    

    题解


    做卷积主要思想是,先把系数表达式转化为点值表达式,而点值表达式相乘的时间复杂度是(O(n))的,唯一需要优化的是这个转化的过程,需要使用fft进行优化,时间负责度可以降为(O(nlogn)),具体算法思想参看
    资料:http://blog.csdn.net/iamzky/article/details/22712347

    参考代码

    #include <queue>
    #include <cmath>
    #include <cstdio>
    #include <complex>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define inf 1000000000
    #define PI acos(-1)
    #define mem(a,x) memset(a,x,sizeof(a))
    using namespace std;
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void Out(ll a){
        if(a<0) putchar('-'),a=-a;
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=200005;
    typedef complex<double> E;
    E a[N],b[N],A[N],c[N];
    char s1[N],s2[N];
    int sum[N],a1[N],a2[N],dig[N],rev[N];
    void FFT(E a[],int n,int flag){
        E x,y;
        for(int i=0;i<n;i++) A[i]=a[rev[i]];
        for(int i=0;i<n;i++) a[i]=A[i];
        for(int i=2;i<=n;i<<=1){
            E wn(cos(2*PI/i),flag*sin(2*PI/i));
            for(int k=0;k<n;k+=i){
                E w(1,0);
                for(int j=k;j<k+i/2;j++){
                    x=a[j];
                    y=a[j+i/2]*w;
                    a[j]=x+y;
                    a[j+i/2]=x-y;
                    w=w*wn;
                }
            }
        }
        if(flag==-1) for(int i=0;i<n;i++) a[i]/=n;
    }
    int main(){
        while(~scanf("%s%s",s1,s2)){
            int len1=strlen(s1),len2=strlen(s2),n,L;
            for(n=1,L=0;n<max(len1,len2);n<<=1,L++);
            n<<=1;L++;
            mem(rev,0);mem(dig,0);
            mem(a1,0);mem(a2,0);
            for(int i=0;i<n;i++){
                int len=0;
                for(int t=i;t;t>>=1) dig[len++]=t&1;
                for(int j=0;j<L;j++) rev[i]=(rev[i]<<1)|dig[j];
            }
            for(int i=0;i<len1;i++) a1[len1-i-1]=s1[i]-'0';
            for(int i=0;i<len2;i++) a2[len2-i-1]=s2[i]-'0';
            for(int i=0;i<n;i++) a[i]=E(a1[i]);
            for(int i=0;i<n;i++) b[i]=E(a2[i]);
            FFT(a,n,1);FFT(b,n,1);
            for(int i=0;i<n;i++) c[i]=a[i]*b[i];
            FFT(c,n,-1);
            for(int i=0;i<n;i++) sum[i]=c[i].real()+0.5;
            for(int i=0;i<n;i++){
                sum[i+1]+=sum[i]/10;
                sum[i]%=10;
            }
            int l=len1+len2-1;
            while(sum[l]==0&&l>0)l--;
            for(int i=l;i>=0;i--)
                putchar(sum[i]+'0');
            putchar('
    ');
        }
        return 0;
    }
    
  • 相关阅读:
    JavaWeb--基本概念
    启动Tomcat错误:The JRE_HOME environment variable is not defined correctly
    时间管理-1-总有一种情况你经历过
    时间管理
    非对称加密-支付宝 堆成加密
    TreeMap底层实现和原理-红黑树
    @Autowired报错原因分析和4种解决方案!
    布隆过滤器的设计原理
    springboot 日期参数前后台转换问题
    设计模式
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/7204414.html
Copyright © 2011-2022 走看看