-
Notifications
You must be signed in to change notification settings - Fork 13
/
FFT (Recursive)
67 lines (61 loc) · 1.2 KB
/
FFT (Recursive)
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
const double PI = 4*atan(1);
const int N=2e5+5;
const int MOD=13313;
int FFT_N=0;
vector<base> omega;
void init_fft(int n)
{
FFT_N = n;
omega.resize(n);
double angle = 2*PI/n;
for(int i=0;i<n;i++)
{
omega[i]=base(cos(i*angle), sin(i*angle));
}
}
void fft(vector<base> &a)
{
int n=a.size();
if(n==1)
return;
int half=n>>1;
vector<base> even(half), odd(half);
for(int i=0, j=0; i<n; i+=2, j++)
{
even[j]=a[i];
odd[j]=a[i+1];
}
fft(even);
fft(odd);
int denominator=FFT_N/n;
for(int i=0;i<half;i++)
{
base cur=odd[i] * omega[i*denominator];
a[i]=even[i] + cur;
a[i+half]=even[i] - cur;
}
}
void multiply(vector<int> &a, vector<int> &b, vector<int> &res)
{
vector<base> fa(a.begin(), a.end());
vector<base> fb(b.begin(), b.end());
int n=1;
while(n<2*max(a.size(), b.size()))
n<<=1;
fa.resize(n);
fb.resize(n);
init_fft(n);
fft(fa);
fft(fb);
for(int i=0;i<n;i++)
fa[i] = conj(fa[i] * fb[i]);
fft(fa);
res.resize(n);
for(int i=0;i<n;i++)
{
res[i]=(long long)(fa[i].real()/n + 0.5);
res[i]%=MOD;
}
}
//Sample Problem 1: https://www.codechef.com/problems/COUNTWAY/
//Sample Solution 1 (Divide and Conquer on Polynomials): https://www.codechef.com/viewsolution/19133506