一个晚上和FFT相爱相杀的故事。。。。。。
反正就是裸的。。。。
然后这个是递归式的 自己还是太弱了。。。。
话说发现自己的代码很长诶。。。。。
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> using namespace std; const double PI=acos(-1); struct Complex { double Real,fake; Complex(){Real=fake=0; } Complex(double r,double f){Real=r,fake=f; } inline friend Complex operator *(Complex a,Complex b) {return (Complex){a.Real*b.Real-a.fake*b.fake,a.fake*b.Real+a.Real*b.fake};} inline friend Complex operator +(Complex a,Complex b) {return (Complex){a.Real+b.Real,a.fake+b.fake};} inline friend Complex operator -(Complex a,Complex b) {return (Complex){a.Real-b.Real,a.fake-b.fake};} inline friend Complex operator -(Complex a,double b) {return (Complex){a.Real-b,a.fake};} inline friend Complex operator -(double a,Complex b) {return (Complex){a-b.Real,0-b.fake};} inline friend Complex operator *(double a,Complex b) {return (Complex){a*b.Real,a*b.fake};} inline friend Complex operator *(Complex a,double b) {return (Complex){b*a.Real,b*a.fake};} }; Complex W; int base=1; char c; inline void read(int &a) { a=0;do c=getchar();while(c<'0'||c>'9'); while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();} struct Complex_Line { Complex *data; int len; inline void build(int a){ data=new Complex[a]; len=a;} }a[1001]; Complex_Line DFT(Complex_Line Tp,int len,int on) { if(len==1)return Tp; Complex_Line a1,a2,y; Complex W=(Complex){cos(2*PI/len),sin(-on*2*PI/len)}; y.build(len); a1.build(len>>1); a2.build(len>>1); for(int i=1;i<=len>>1;i++) a1.data[i-1]=Tp.data[(i<<1)-2],a2.data[i-1]=Tp.data[(i<<1)-1]; a1=DFT(a1,len>>1,on), a2=DFT(a2,len>>1,on); Complex w=(Complex){1,0}; for(int i=1;i<=len>>1;i++) y.data[i-1]=a1.data[i-1]+a2.data[i-1]*w, y.data[i-1+(len>>1)]=a1.data[i-1]-a2.data[i-1]*w, w=w*W; return y; } int sum[1000001]; char s1[100001],s2[100001]; int main() { int len1,len2; int n; read(n); Complex_Line a,b; scanf("%s",s1); scanf("%s",s2); len1=strlen(s1),len2=strlen(s2); while(base<n)base<<=1; base<<=1; a.build(base); b.build(base); W=(Complex){cos(2*PI/base),sin(2*PI/base)}; for(int i=0;i<len1;i++) a.data[i]=(Complex){s1[len1-i-1]-'0',0}; for(int i=len1;i<base;i++) a.data[i]=(Complex){0,0}; for(int i=0;i<len2;i++) b.data[i]=(Complex){s2[len2-i-1]-'0',0}; for(int i=len2;i<base;i++) b.data[i]=(Complex){0,0}; a=DFT(a,base,1); b=DFT(b,base,1); for(int i=1;i<=base;i++) a.data[i-1]=a.data[i-1]*b.data[i-1]; a=DFT(a,base,-1); for(int i=0;i<base;i++) a.data[i].Real/=base; memset(sum,0,sizeof(sum)); int len3=len2+len1; for(int i=0;i<base;i++) sum[i]=(int){a.data[i].Real+0.5}; for(int i=0;i<len3;i++) sum[i+1]+=sum[i]/10,sum[i]%=10; while(!sum[len3])len3--; for(int i=len3;i!=-1;i--) putchar('0'+sum[i]); putchar('\n'); return 0; }
1/22/2016
去黄学长哪里学了一下Rader 还有c++自带的complex。。
感觉那个Rader很叼的样子
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<complex> using namespace std; #define com complex<double> char c; inline void read(int &a) { a=0;do c=getchar();while(c<'0'||c>'9'); while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar(); } inline void Get(int &a) { a=0;do c=getchar();while(c<'0'||c>'9'); a=c-'0'; } int St[1000001]; struct Complex_Line { int n; com *Line; inline void Begin(int t){Line=new com[n=t];} inline void print() { for(int i=0;i<n;i++) St[i]=(Line[i].real()+0.1); St[n]=0; for(int i=0;i<n;i++) { St[i+1]+=St[i]/10, St[i]%=10; if(St[i]<0)St[i+1]--,St[i]+=10; } int len=n; if(St[len+1])len++; while(!St[len])len--; printf("%d",St[len]); while(len--) putchar('0'+St[len]); } }; const double pi=acos(-1); int rev[1000001]; inline void Beg(int Len) { int L=0,t=1; while((1<<L)^Len)L++; for(int i=0;i<Len;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1)); } inline Complex_Line Rev(Complex_Line a) { Complex_Line Re; Re.Begin(a.n); for(int i=0;i<a.n;i++) Re.Line[rev[i]]=a.Line[i]; return Re; } inline Complex_Line FFT(Complex_Line t,int f) { int n=t.n; Complex_Line A=Rev(t); for(int i=1;i<n;i<<=1) { com W0=com(cos(pi/i),f*sin(pi/i)); for(int j=0;j<n;j+=(i<<1)) { com W(1,0); for(int k=0;k<i;k++) { com x=A.Line[j+k],y=W*A.Line[j+k+i]; A.Line[j+k]=x+y; A.Line[j+k+i]=x-y; W*=W0; } } } if(f==-1) for(int j=0;j<n;j++) A.Line[j]/=n; return A; } int main() { int n; read(n); int tp=n; while(tp^(tp&-tp)) { tp^=tp&-tp; } tp<<=2; int i; Complex_Line A,B; A.Begin(tp); B.Begin(tp); int j; for(i=1;i<=n;i++) { Get(j); A.Line[n-i]=j; } for(i=n;i<tp;i++) A.Line[i]=com(0,0); for(i=1;i<=n;i++) Get(j),B.Line[n-i]=j; for(i=n;i<tp;i++) B.Line[i]=com(0,0); Beg(tp); A=FFT(A,1); B=FFT(B,1); for(i=0;i<tp;i++) A.Line[i]=A.Line[i]*B.Line[i]; A=FFT(A,-1); A.print(); return 0; }