P1919【模板】A*B Problem升级版(FFT快速傅里叶)
P1919 【模板】A*B Problem升级版(FFT快速傅里叶)
题目描述
给出两个n位10进制整数x和y,你需要计算x*y。
输入输出格式
输入格式:
第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。
输出格式:
输出一行,即x*y的结果。(注意判断前导0)
输入输出样例
说明
数据范围:
n<=60000
来源:bzoj2179
本题数据为洛谷自造数据,使用CYaRon耗时5分钟完成数据制作。
只有70。。。懒得调了
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<complex> #define N 131072 #define pi acos(-1) using namespace std; typedef complex<double> E; int read() { int x,f=1;char s=getchar(); while(s>'9' || s<'0'){if(s=='-')f=-1;s=getchar();} while(s<='9' && s>='0'){x=x*10+s-'0';s=getchar();} return x*f; } char sa[N],sb[N]; E a[N],b[N]; int re[N],c[N],n,m,L; void fft(E *a,int f) { for(int i=0;i<m;i++)if(i<re[i])swap(a[i],a[re[i]]); for(int i=1;i<m;i<<=1) { E wn(cos(pi/i),f*sin(pi/i)); for(int j=0;j<m;j+=(i<<1)) { E w(1,0); for(int k=0;k<i;k++,w*=wn) { E x=a[j+k],y=w*a[j+k+i]; a[j+k]=x+y;a[j+k+i]=x-y; } } } if(f==-1)for(int i=0;i<m;i++)a[i]/=m; } int main() { n=read();n--; scanf("%s",sa);scanf("%s",sb); for(int i=0;i<=n;i++)a[i]=sa[n-i]-'0',b[i]=sb[n-i]-'0'; //for(int i=0;i<=n;i++)printf("%d",(int)(a[i].real()+0.1)); n<<=1;for(m=1;m<=n;m<<=1)L++;L--; for(int i=0;i<m;i++)re[i]=(re[i>>1]>>1)|((i&1)<<L); fft(a,1);fft(b,1); for(int i=0;i<m;i++)a[i]=a[i]*b[i]; fft(a,-1); for(int i=0;i<=m;i++)c[i]=(int)(a[i].real()+0.1); for(int i=0;i<=m;i++) if(c[i]>=10) { c[i+1]+=c[i]/10,c[i]%=10; if(i==m)m++; } while(!c[m])m--; for(int i=m;i>=0;i--)printf("%d",c[i]); return 0; }