【UOJ 34】 多项式乘法 (FFT)
【题意】 给你两个多项式,请输出乘起来后的多项式。
先打一个递归版本的模板。。。
#include<cstdio> #include<iostream> #include<cmath> #include<memory.h> #define N 400010 using namespace std; const double pi=acos(-1); struct P { double x,y; P() {x=y=0;} P(double x,double y):x(x),y(y){} }a[N],b[N]; P operator + (P x,P y) {return P(x.x+y.x,x.y+y.y);} P operator - (P x,P y) {return P(x.x-y.x,x.y-y.y);} P operator * (P x,P y) {return P(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);} void fft(P *s,int n,int t) { if(n==1) return; P a0[n>>1],a1[n>>1]; for(int i=0;i<=n;i+=2) a0[i>>1]=s[i],a1[i>>1]=s[i+1]; fft(a0,n>>1,t);fft(a1,n>>1,t); P wn(cos(2*pi/n),t*sin(2*pi/n)),w(1,0); for(int i=0;i<(n>>1);i++,w=w*wn) s[i]=a0[i]+w*a1[i],s[i+(n>>1)]=a0[i]-w*a1[i]; //w^2=(w+(n>>1))^2 均匀分布在圆上面? //w[i^2,n]=w[i/2,n/2] 折半引理 //s[i]=a0’(i^2)+i*a1’(i^2)=a0(i)+i*a1(i) //s[i+n>>1]=a0’((i+n>>1)^2)+i*a1’((i+n>>1)^2)=a0’(i^2)-i*a1’(i^2) //因为i=-(i+n>>1) 折半引理 } int main() { int n,m,nn; scanf("%d%d",&n,&m); memset(a,0,sizeof(a));memset(b,0,sizeof(b)); for(int i=0;i<=n;i++) scanf("%lf",&a[i].x); for(int i=0;i<=m;i++) scanf("%lf",&b[i].x); nn=1;while (nn<=n+m) nn<<=1; fft(a,nn,1);fft(b,nn,1); for(int i=0;i<=nn;i++) a[i]=a[i]*b[i]; fft(a,nn,-1); for(int i=0;i<=n+m;i++) printf("%d ",(int)(a[i].x/nn+0.5)); return 0; }
2017-03-04 08:51:27