2179: FFT快速傅立叶
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 3683 Solved: 1955
[Submit][Status][Discuss]
Description
给出两个n位10进制整数x和y,你需要计算x*y。
Input
第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。
Output
输出一行,即x*y的结果。
Sample Input
1
3
4
3
4
Sample Output
12
数据范围:
n<=60000
数据范围:
n<=60000
HINT
Source
FFT的板子题
#include <bits/stdc++.h> inline int read(){ int x=0;int f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} return x*f; } const int MAXN=1e6+10; const double pi=acos(-1); int R[MAXN],L,H; long long ans[MAXN]={}; struct complex{ double r,v; complex(double a=0,double b=0):r(a),v(b){} inline complex operator + (const complex &b) {return complex(r+b.r,v+b.v);} inline complex operator * (const complex &b) {return complex(r*b.r-v*b.v,r*b.v+v*b.r);} inline complex operator - (const complex &b) {return complex(r-b.r,v-b.v);} }a[MAXN],b[MAXN],w[MAXN]; inline void swap(complex& a,complex& b) {complex t(a);a=b;b=t;} inline void FFT(complex *a,int f){ for(int i=0;i<L;i++){ if(i<R[i]) swap(a[i],a[R[i]]); } for(int len=2;len<=L;len<<=1){ int l=len>>1; complex wn(cos(pi/l),f*sin(pi/l)); for(int i=1;i<l;i++){ w[i]=w[i-1]*wn; } for(int st=0;st<L;st+=len){ for(int k=0;k<l;k++){ complex x=a[st+k];complex y=w[k]*a[st+k+l]; //printf("%lf %lf ",x.r,x.v); a[st+k]=x+y;a[st+k+l]=x-y; } } } if(f==-1){ for(int i=0;i<L;i++){ a[i].r=a[i].r/L; } } } char ch1[300010],ch2[300010]; int main(){ w[0].r=1; scanf("%s%s",ch1+1,ch2+1); int n=strlen(ch1+1); int m=strlen(ch2+1); for(int len=0,i=n;i;i--,len++) a[len]=ch1[i]-'0'; for(int len=0,i=m;i;i--,len++) b[len]=ch2[i]-'0'; L=1; while(L<n+m) L<<=1,H++; for(int i=0;i<L;i++){ R[i]=(R[i>>1]>>1)|((i&1)<<(H-1)); } FFT(a,1);FFT(b,1); for(int i=0;i<L;i++){ a[i]=a[i]*b[i]; } FFT(a,-1); for(int i=0;i<n+m-1;i++){ ans[i]=1LL*(a[i].r+0.5); } int len=300000; for(int i=0;i<=len;i++){ ans[i+1]+=ans[i]/10; ans[i]%=10; } while(ans[len]==0) len--; for(int i=len;i>=0;i--){ printf("%lld",ans[i]); } return 0; }