HDU_1402_A * B Problem Plus

来源:互联网 发布:舟山公务员网络学堂 编辑:程序博客网 时间:2024/06/06 08:31

A * B Problem Plus

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 22061    Accepted Submission(s): 5501


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
1210002
 

Sample Output
22000
 

Author
DOOM III

  • 数据量5w
  • 简单乘法运算n^2复杂度显然不可行
  • 现在将整数乘法看成变量x=10的多项式相乘
  • 每一位上的数字为各项系数
  • 用FFT计算卷积,把复杂度降到nlogn
  • 详见代码FFT模板

#include <iostream>#include <string>#include <cstdio>#include <cstring>#include <algorithm>#include <climits>#include <cmath>#include <vector>#include <queue>#include <stack>#include <set>#include <map>using namespace std;typedef long long           LL ;typedef unsigned long long ULL ;const int    maxn = 140000 + 10;const int    inf  = 0x3f3f3f3f ;const int    npos = -1         ;const int    mod  = 1e9 + 7    ;const int    mxx  = 100 + 5    ;const double eps  = 1e-6       ;const double PI   = acos(-1.0) ;struct Complex{double r, i;Complex(double x=0.0, double y=0.0){reset(x,y);}void reset(double x, double y){r=x;i=y;}Complex operator + (const Complex &B){return Complex((r+B.r),(i+B.i));}Complex operator - (const Complex &B){return Complex((r-B.r),(i-B.i));}Complex operator * (const Complex &B){return Complex((r*B.r-i*B.i),(r*B.i+i*B.r));}};Complex A[maxn];void FFT(Complex *a, int n, int op){for(int i=0;i<n;i++){int j=0;for(int k=0;(1<<k)<n;k++){j<<=1;if(i & (1<<k))j|=1;}A[j]=a[i];}for(int d=0;(1<<d)<n;d++){int m=1<<d;int m2=m<<1;double p0=PI/m*op;Complex unit_p0(cos(p0),sin(p0));for(int i=0;i<n;i+=m2){Complex unit(1,0);for(int j=0;j<m;j++){Complex &p1=A[i+j+m], &p2=A[i+j];Complex t=unit*p1;p1=p2-t;p2=p2+t;unit=unit*unit_p0;}}}if(-1==op)for(int i=0;i<n;i++){A[i].r/=n;A[i].i/=n;}for(int i=0;i<n;i++)a[i]=A[i];}Complex c[maxn], d[maxn];char a[maxn], b[maxn];int f[maxn], la, lb, n, sa, sb, flag;int main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);while(~scanf("%s",a)){la=strlen(a);sa=0;while((1<<sa)<la)sa++;scanf("%s",b);lb=strlen(b);sb=0;while((1<<sb)<lb)sb++;n=1<<max(sa+1,sb+1);for(int i=0;i<n;i++){if(i<la){c[i].reset(a[la-i-1]-'0',0);}else{c[i].reset(0,0);}if(i<lb){d[i].reset(b[lb-i-1]-'0',0);}else{d[i].reset(0,0);}}FFT(c,n,1);FFT(d,n,1);for(int i=0;i<n;i++)c[i]=c[i]*d[i];FFT(c,n,-1);for(int i=0;i<n;i++)f[i]=(int)(c[i].r+0.5);for(int i=0;i<n-1;i++){f[i+1]+=f[i]/10;f[i]%=10;}flag=0;for(int i=n-1;i>=0;i--){if(f[i]){printf("%d",f[i]);flag=1;}else if(flag || 0==i){printf("0");}}puts("");}return 0;}


原创粉丝点击