zoukankan      html  css  js  c++  java
  • HDU1402:A * B Problem Plus(FFT与大数乘法)

    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

    把每一位看成ai*10^i,然后就是两个多项式相乘。利用FFT,把复杂度降到O(nlogn)。

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=200010;
    const double pi=acos(-1.0);
    struct complex
    {
        double r,i;
        complex(){};
        complex(double rr,double ii):r(rr),i(ii){}
        complex friend operator +(complex a,complex b){ return complex(a.r+b.r,a.i+b.i); }
        complex friend operator -(complex a,complex b) { return complex(a.r-b.r,a.i-b.i);}
        complex friend operator *(complex a,complex b) { return complex(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);}
    }tmp[maxn];
    struct DFT{
        complex a[maxn];
        void fft(int sz,int bg,int step,int opt){
           if(sz==1) return;  int m=sz>>1;
           fft(m,bg,step<<1,opt); fft(m,bg+step,step<<1,opt);
           complex w=complex(1,0),t=complex(cos(2.0*pi/sz),sin(2.0*pi*opt/sz)); 
           for(int k=0;k<m;k++)
           {
                int pos=2*step*k;
              tmp[k]=a[pos+bg]+w*a[pos+bg+step];
              tmp[k+m]=a[pos+bg]-w*a[pos+bg+step];
              w=w*t;
           }
           for(int i=0;i!=sz;i++) a[i*step+bg]=tmp[i];
        }
    }A,B;
    char c[maxn]; int ans[maxn+10];
    int main()
    {
        while(~scanf("%s",c)){    
            int L1=strlen(c),L2,len=1;
            for(int i=0;i<L1;i++) A.a[i].r=c[L1-i-1]-'0',A.a[i].i=0;
            scanf("%s",c);  L2=strlen(c);
            for(int i=0;i<L2;i++) B.a[i].r=c[L2-i-1]-'0',B.a[i].i=0;
            
            while(len<L1+L2+2) len<<=1;
            
            for(int i=L1;i<=len;i++) A.a[i].r=A.a[i].i=0;
            for(int i=L2;i<=len;i++) B.a[i].r=B.a[i].i=0;
            
            A.fft(len,0,1,1); B.fft(len,0,1,1);
            for(int i=0;i<len;i++) A.a[i]=A.a[i]*B.a[i];
            A.fft(len,0,1,-1);
            
            int head=0;
            for(int i=0;i<len;i++) ans[i]=(int)(A.a[i].r/len+0.5);
            for(int i=0;i<len;i++){
                ans[i+1]+=ans[i]/10; ans[i]%=10;
                if(ans[i]>0) head=i;
            }
            
            for(int i=head;i>=0;i--) printf("%d",ans[i]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    c#数据类型
    遮罩层
    图片轮播
    js 获取浏览器高度和宽度值
    bootstrap、jquery
    洛谷P1442 铁球落地 题解
    HDU3016 Man Down 题解
    POJ2892 Tunnel Warfare 题解
    HDU2795 Billboard 题解
    CF920F SUM and REPLACE 题解
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8723452.html
Copyright © 2011-2022 走看看