【UOJ 34】多项式乘法
FFT模板
迭代的还没会 先写了个递归的
define的PI 我也是神了!! 少上一位就会WA
模板看的hzwer的
因为 PI较短【...】所以递归的跑的和迭代的一样快 23333333
还差的几点:
1. acos要用
2.complex要自己写(yts1999大爷说会被卡)
3. 要改成迭代的
1 #include <cstdio>
2 #include <cmath>
3 #include <complex>
4 #include <iostream>
5 using namespace std;
6 #define PI 3.14159265
7 //const double PI =acos(-1);
8 int n,m;
9 complex<double> a[300000+1],b[300000+1];
10
11 void FFT(complex<double> x[],int lenth,int type)
12 {
13 if(lenth==1) return ;
14 complex<double> p[lenth/2],q[lenth/2];
15 for(int i=0;i<lenth;i++)
16 if(i&1) p[i/2]=x[i];
17 else q[i/2]=x[i];
18 FFT(q,lenth/2,type);
19 FFT(p,lenth/2,type);
20 complex <double> wn(cos(2*PI/lenth),sin(type*2*PI/lenth)),t,w(1,0);
21 for(int i=0;i<lenth/2;i++)
22 {
23 t=w*p[i];
24 x[i]=q[i]+t;
25 x[i+lenth/2]=q[i]-t;
26 w*=wn;
27 }
28 }
29 int main()
30 {
31 scanf("%d %d",&n,&m);int tmp;
32
33 for(int i=0;i<=n;i++) scanf("%d",&tmp),a[i]=tmp;
34 for(int i=0;i<=m;i++) scanf("%d",&tmp),b[i]=tmp;
35 m+=n;m++;
36 n=1;
37 for(;n<m;n*=2);
38 FFT(a,n,1);
39 FFT(b,n,1);
40 for(int i=0;i<n;i++) a[i]*=b[i];
41 FFT(a,n,-1);
42 for(int i=0;i<m;i++) printf("%d ",(int)(a[i].real()/n+0.5));
43 return 0;
44 }
2 #include <cmath>
3 #include <complex>
4 #include <iostream>
5 using namespace std;
6 #define PI 3.14159265
7 //const double PI =acos(-1);
8 int n,m;
9 complex<double> a[300000+1],b[300000+1];
10
11 void FFT(complex<double> x[],int lenth,int type)
12 {
13 if(lenth==1) return ;
14 complex<double> p[lenth/2],q[lenth/2];
15 for(int i=0;i<lenth;i++)
16 if(i&1) p[i/2]=x[i];
17 else q[i/2]=x[i];
18 FFT(q,lenth/2,type);
19 FFT(p,lenth/2,type);
20 complex <double> wn(cos(2*PI/lenth),sin(type*2*PI/lenth)),t,w(1,0);
21 for(int i=0;i<lenth/2;i++)
22 {
23 t=w*p[i];
24 x[i]=q[i]+t;
25 x[i+lenth/2]=q[i]-t;
26 w*=wn;
27 }
28 }
29 int main()
30 {
31 scanf("%d %d",&n,&m);int tmp;
32
33 for(int i=0;i<=n;i++) scanf("%d",&tmp),a[i]=tmp;
34 for(int i=0;i<=m;i++) scanf("%d",&tmp),b[i]=tmp;
35 m+=n;m++;
36 n=1;
37 for(;n<m;n*=2);
38 FFT(a,n,1);
39 FFT(b,n,1);
40 for(int i=0;i<n;i++) a[i]*=b[i];
41 FFT(a,n,-1);
42 for(int i=0;i<m;i++) printf("%d ",(int)(a[i].real()/n+0.5));
43 return 0;
44 }
Upd:1.24 WC RP++a啊
#include <cstdio>
#include <iostream>
#include <complex>
#include <cmath>
using namespace std;
const double PI=acos(-1);
//#define PI 3.14159265
#define C complex<double>
C a[300000],b[300000];
int rev[300000];
int n,m;
void FFT(C x[],int type)
{
for(int i=0;i<n;i++) if(rev[i]<i) swap(x[i],x[rev[i]]);
// for(int i=0;i<n;i++) cout<<x[i]<<' ';cout<<endl;
for(int i=2;i<=n;i*=2)
{
C wn(cos(2*PI/i),type*sin(2*PI/i));
// cout<<wn<<endl;
for(int j=0;j<n;j+=i)
{
C w(1,0),t,tmp;
for(int k=0;k<i/2;k++)
{
tmp=x[j+k];
t=x[j+k+i/2]*w;
x[j+k]=tmp+t;
x[j+k+i/2]=tmp-t;
w=w*wn;
}
}
}
}
int main()
{
// freopen("a.in","r",stdin);
scanf("%d %d",&n,&m);
for(int i=0;i<=n;i++) scanf("%lf",&a[i]);
for(int i=0;i<=m;i++) scanf("%lf",&b[i]);
m=m+n+1;
int ll=1;
for(n=1;n<m;n*=2) ll++; ll-=2;//cout<<ll<<endl;
for(int i=0;i<n;i++) rev[i]=( ( rev[i/2]>>1 ) | ( (i&1)<<ll) );
FFT(a,1);
FFT(b,1);
for(int i=0;i<n;i++) a[i]=a[i]*b[i];
FFT(a,-1);
for(int i=0;i<m;i++) printf("%d ",(int)(a[i].real()/n+0.5));
return 0;
}
#include <iostream>
#include <complex>
#include <cmath>
using namespace std;
const double PI=acos(-1);
//#define PI 3.14159265
#define C complex<double>
C a[300000],b[300000];
int rev[300000];
int n,m;
void FFT(C x[],int type)
{
for(int i=0;i<n;i++) if(rev[i]<i) swap(x[i],x[rev[i]]);
// for(int i=0;i<n;i++) cout<<x[i]<<' ';cout<<endl;
for(int i=2;i<=n;i*=2)
{
C wn(cos(2*PI/i),type*sin(2*PI/i));
// cout<<wn<<endl;
for(int j=0;j<n;j+=i)
{
C w(1,0),t,tmp;
for(int k=0;k<i/2;k++)
{
tmp=x[j+k];
t=x[j+k+i/2]*w;
x[j+k]=tmp+t;
x[j+k+i/2]=tmp-t;
w=w*wn;
}
}
}
}
int main()
{
// freopen("a.in","r",stdin);
scanf("%d %d",&n,&m);
for(int i=0;i<=n;i++) scanf("%lf",&a[i]);
for(int i=0;i<=m;i++) scanf("%lf",&b[i]);
m=m+n+1;
int ll=1;
for(n=1;n<m;n*=2) ll++; ll-=2;//cout<<ll<<endl;
for(int i=0;i<n;i++) rev[i]=( ( rev[i/2]>>1 ) | ( (i&1)<<ll) );
FFT(a,1);
FFT(b,1);
for(int i=0;i<n;i++) a[i]=a[i]*b[i];
FFT(a,-1);
for(int i=0;i<m;i++) printf("%d ",(int)(a[i].real()/n+0.5));
return 0;
}