[FFT]luogu P1919 A*B Problem升级版
https://www.luogu.org/problemnew/show/P1919
分析
可以把一个数化为多项式的系数,如233
3+3x+2x^2
然后便可以进行快速傅里叶转换了
注意进位
#include <iostream> #include <cstdio> #include <cmath> #include <complex> using namespace std; typedef complex<double> cn; const int N=262144; const double pi=3.14159265358979; int rev[N]; cn a[N],b[N]; int n,mx,bit; bool p; void Get_Rev(int mx) { for (int i=0;i<mx;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<bit-1); } void FFT (cn *a,int ir) { for (int i=0;i<mx;i++) if (i<rev[i]) swap(a[i],a[rev[i]]); for (int i=1;i<mx;i<<=1) { cn wn=exp(cn(0,ir*pi/i)); for (int len=i<<1,l=0;l<mx;l+=len) { cn wk=cn(1,0); for (int j=l;j<l+i;j++) { cn x=a[j],y=wk*a[j+i]; a[j]=x+y;a[j+i]=x-y; wk*=wn; } } } if (ir<0) for (int i=0;i<mx;i++) a[i]/=mx; } int main() { scanf("%d",&n); for (int i=0;i<n;i++) { char c; do { scanf("%c",&c); } while (c<'0'||c>'9'); a[n-1-i]=(double)c-48; } for (int i=0;i<n;i++) { char c; do { scanf("%c",&c); } while (c<'0'||c>'9'); b[n-1-i]=(double)c-48; } n--; mx=1;while (mx<=2*n) mx<<=1,bit++; Get_Rev(mx); FFT(a,1);FFT(b,1); for (int i=0;i<mx;i++) a[i]=a[i]*b[i]; FFT(a,-1); mx=2*n; for (int i=0;i<=mx;i++) { a[i+1].real()+=(int)(a[i].real()+0.5)/10,a[i].real()=(int)(a[i].real()+0.5)%10; if (a[mx+1].real()>0) mx++; } for (int i=mx;i>=0;i--) if (p||a[i].real()>0) printf("%d",(int)(a[i].real()+0.5)),p=1; }
在日渐沉没的世界里,我发现了你。