-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFFTPolyMult.cpp
85 lines (85 loc) · 2.07 KB
/
FFTPolyMult.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <bits/stdc++.h>
#define cpx complex<double>
#define pi 3.14159265359
using namespace std;
vector<cpx> FFT(vector<int> vc){
int n=vc.size();
if(n==1){
vector<cpx> tmp;
tmp.push_back(cpx(1.0*vc[0],0.0));
return tmp;
}
int half=n/2;
vector<int> v0,v1;
for(int i=0;i<half;i++){
v0.push_back(vc[i<<1]);
v1.push_back(vc[i<<1^1]);
}
vector<cpx> Y0=FFT(v0),Y1=FFT(v1),foo(n);
cpx w(1,0),wn(cos(2*pi/n),sin(2*pi/n));
for(int i=0;i<half;i++){
foo[i]=Y0[i]+w*Y1[i];
foo[i+half]=Y0[i]-w*Y1[i];
w*=wn;
}
return foo;
}
vector<cpx> iFFT(vector<cpx> vc){
int n=vc.size();
if(n==1){
return vc;
}
int half=n/2;
vector<cpx> v0,v1;
for(int i=0;i<half;i++){
v0.push_back(vc[i<<1]);
v1.push_back(vc[i<<1^1]);
}
vector<cpx> Y0=iFFT(v0),Y1=iFFT(v1),foo(n);
cpx w(1,0),wn(cos(2*pi/n),sin(-2*pi/n));
for(int i=0;i<half;i++){
foo[i]=Y0[i]+w*Y1[i];
foo[i+half]=Y0[i]-w*Y1[i];
w*=wn;
}
return foo;
}
vector<cpx> comMul(vector<cpx> c1,vector<cpx> c2){
int n1=c1.size(),n2=c2.size(),mx,mn;
mx=max(n1,n2);
mn=min(n1,n2);
vector<cpx> res;
for(int i=0;i<mn;i++) res.push_back(c1[i]*c2[i]);
for(;mn<mx;mn++) res.push_back(cpx(0,0));
return res;
}
int main() {
vector<cpx> coef;
vector<int> coef1,coef2;
int n,m,tmp;
scanf("%d %d",&n,&m); // n and m degree of two polynomials
n++;
m++;
for(int i=n;i--;) { // enter n+1 coefficients as c0+c1*x+c2*x*x+....
scanf("%d",&tmp);
coef1.push_back(tmp);
}
tmp=1;
while(tmp<=n) tmp<<=1;
for(int i=n;i<tmp;i++) coef1.push_back(0);
tmp<<=1;
for(int i=tmp>>1;i<tmp;i++) coef1.push_back(0);
for(int i=m;i--;) { // enter m+1 coefficients as c0+c1*x+c2*x*x+....
scanf("%d",&tmp);
coef2.push_back(tmp);
}
tmp=1;
while(tmp<=m) tmp<<=1;
for(int i=m;i<tmp;i++) coef2.push_back(0);
tmp<<=1;
for(int i=tmp>>1;i<tmp;i++) coef2.push_back(0);
coef=iFFT(comMul(FFT(coef1),FFT(coef2)));
for(int i=0;i<(n+m-1);i++){
cout<<round(real(coef[i]))/tmp<<" "; // coefficients of polynomial which is product of
} // two polunomials
}