数学(三) |
难度级别: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; }
时间: 2024-10-07 05:28:59