1
1
namespace fft {
2
- const int N = 1 << 20 , M = 31768 ;
2
+ const int N = 1 << 20 , M = 31768 ;
3
3
4
4
struct Complex {
5
5
double x, y;
6
6
7
- Complex () { x = y = 0 ; }
7
+ Complex () { x = y = 0 ; }
8
8
9
- Complex (double _x, double _y) { x = _x, y = _y; }
9
+ Complex (double _x, double _y) { x = _x, y = _y; }
10
10
11
- Complex operator +(const Complex &r) const {
12
- return Complex (x + r.x , y + r.y );
11
+ Complex operator + (const Complex &r) const {
12
+ return Complex (x + r.x , y + r.y );
13
13
}
14
14
15
- Complex operator -(const Complex &r) const {
16
- return Complex (x - r.x , y - r.y );
15
+ Complex operator - (const Complex &r) const {
16
+ return Complex (x - r.x , y - r.y );
17
17
}
18
18
19
- Complex operator *(const double k) const {
20
- return Complex (x * k, y * k);
19
+ Complex operator * (const double k) const {
20
+ return Complex (x * k, y * k);
21
21
}
22
22
23
- Complex operator /(const double k) const {
24
- return Complex (x / k, y / k);
23
+ Complex operator / (const double k) const {
24
+ return Complex (x / k, y / k);
25
25
}
26
26
27
- Complex operator *(const Complex &r) const {
28
- return Complex (x * r.x - y * r.y , x * r.y + y * r.x );
27
+ Complex operator * (const Complex &r) const {
28
+ return Complex (x * r.x - y * r.y , x * r.y + y * r.x );
29
29
}
30
30
31
- int operator =(const int a) {
32
- *this = Complex (a, 0 );
31
+ int operator = (const int a) {
32
+ *this = Complex (a, 0 );
33
33
return a;
34
34
}
35
35
36
- Complex conj () const {
37
- return Complex (x, -y);
36
+ Complex conj () const {
37
+ return Complex (x, -y);
38
38
}
39
39
};
40
40
41
- const double pi = acos(-1.0 );
41
+ const double pi = acos (-1.0 );
42
42
Complex w[N];
43
43
int rev[N];
44
44
45
- void init (int L) {
46
- int n = 1 << L;
45
+ void init (int L) {
46
+ int n = 1 << L;
47
47
for (int i = 0 ; i < n; ++i) {
48
48
double ang = 2 * pi * i / n;
49
- w[i] = Complex (cos (ang), sin (ang));
50
- rev[i] = (rev[i >> 1 ] >> 1 ) | ((i & 1 ) << (L - 1 ));
49
+ w[i] = Complex (cos (ang), sin (ang));
50
+ rev[i] = (rev[i>> 1 ]>> 1 ) | ((i & 1 )<< (L - 1 ));
51
51
}
52
52
}
53
53
54
- void trans (Complex P[], int n, int oper) {
54
+ void trans (Complex P[], int n, int oper) {
55
55
for (int i = 0 ; i < n; i++) {
56
56
if (i < rev[i]) {
57
- std::swap (P[i], P[rev[i]]);
57
+ std::swap (P[i], P[rev[i]]);
58
58
}
59
59
}
60
- for (int d = 0 ; (1 << d) < n; d++) {
61
- int m = 1 << d, m2 = m * 2 , rm = n / m2;
60
+ for (int d = 0 ; (1 << d) < n; d++) {
61
+ int m = 1 << d, m2 = m * 2 , rm = n / m2;
62
62
for (int i = 0 ; i < n; i += m2) {
63
63
for (int j = 0 ; j < m; j++) {
64
64
Complex &P1 = P[i + j + m], &P2 = P[i + j];
@@ -77,91 +77,89 @@ namespace fft {
77
77
78
78
Complex A[N], B[N], C1[N], C2[N];
79
79
80
- std::vector <ll> conv (const std::vector<int > &a, const std::vector<int > &b) {
81
- int n = a.size (), m = b.size (), L = 0 , s = 1 ;
80
+ std::vector<ll> conv (const std::vector<int > &a, const std::vector<int > &b) {
81
+ int n = a.size (), m = b.size (), L = 0 , s = 1 ;
82
82
while (s <= n + m - 2 ) s <<= 1 , ++L;
83
- init (L);
83
+ init (L);
84
84
for (int i = 0 ; i < s; ++i) {
85
- A[i] = i < n ? Complex (a[i], 0 ) : Complex ();
86
- B[i] = i < m ? Complex (b[i], 0 ) : Complex ();
85
+ A[i] = i < n ? Complex (a[i], 0 ) : Complex ();
86
+ B[i] = i < m ? Complex (b[i], 0 ) : Complex ();
87
87
}
88
- trans (A, s, 1 );
89
- trans (B, s, 1 );
88
+ trans (A, s, 1 );
89
+ trans (B, s, 1 );
90
90
for (int i = 0 ; i < s; ++i) {
91
91
A[i] = A[i] * B[i];
92
92
}
93
93
for (int i = 0 ; i < s; ++i) {
94
- w[i] = w[i].conj ();
94
+ w[i] = w[i].conj ();
95
95
}
96
- trans (A, s, -1 );
97
- std::vector <ll> res (n + m - 1 );
96
+ trans (A, s, -1 );
97
+ std::vector<ll> res (n + m - 1 );
98
98
for (int i = 0 ; i < n + m - 1 ; ++i) {
99
- res[i] = (ll)(A[i].x + 0.5 );
99
+ res[i] = (ll) (A[i].x + 0.5 );
100
100
}
101
101
return res;
102
102
}
103
103
104
- std::vector <ll> fast_conv (const std::vector<int > &a, const std::vector<int > &b) {
105
- int n = a.size (), m = b.size (), L = 0 , s = 1 ;
104
+ std::vector<ll> fast_conv (const std::vector<int > &a, const std::vector<int > &b) {
105
+ int n = a.size (), m = b.size (), L = 0 , s = 1 ;
106
106
for (; s <= n + m - 2 ; s <<= 1 , ++L);
107
107
s >>= 1 , --L;
108
- init (L);
108
+ init (L);
109
109
for (int i = 0 ; i < s; ++i) {
110
- A[i].x = (i << 1 ) < n ? a[i << 1 ] : 0 ;
111
- B[i].x = (i << 1 ) < m ? b[i << 1 ] : 0 ;
112
- A[i].y = (i << 1 | 1 ) < n ? a[i << 1 | 1 ] : 0 ;
113
- B[i].y = (i << 1 | 1 ) < m ? b[i << 1 | 1 ] : 0 ;
110
+ A[i].x = (i<< 1 ) < n ? a[i<< 1 ] : 0 ;
111
+ B[i].x = (i<< 1 ) < m ? b[i<< 1 ] : 0 ;
112
+ A[i].y = (i<< 1 | 1 ) < n ? a[i<< 1 | 1 ] : 0 ;
113
+ B[i].y = (i<< 1 | 1 ) < m ? b[i<< 1 | 1 ] : 0 ;
114
114
}
115
- trans (A, s, 1 );
116
- trans (B, s, 1 );
115
+ trans (A, s, 1 );
116
+ trans (B, s, 1 );
117
117
for (int i = 0 ; i < s; ++i) {
118
118
int j = (s - i) & (s - 1 );
119
- C1[i] = (Complex (4 , 0 ) * (A[j] * B[j]).conj () -
120
- (A[j].conj () - A[i]) * (B[j].conj () - B[i]) * (w[i] + Complex (1 , 0 ))) * Complex (0 , 0.25 );
119
+ C1[i] = (Complex (4 , 0 ) * (A[j] * B[j]).conj () -
120
+ (A[j].conj () - A[i]) * (B[j].conj () - B[i]) * (w[i] + Complex (1 , 0 ))) * Complex (0 , 0.25 );
121
121
}
122
- std::reverse (w + 1 , w + s);
123
- trans (C1, s, -1 );
124
- std::vector <ll> res (n + m);
122
+ std::reverse (w + 1 , w + s);
123
+ trans (C1, s, -1 );
124
+ std::vector<ll> res (n + m);
125
125
for (int i = 0 ; i <= (n + m - 1 ) / 2 ; ++i) {
126
- res[i << 1 ] = ll (C1[i].y + 0.5 );
127
- res[i << 1 | 1 ] = ll (C1[i].x + 0.5 );
126
+ res[i<< 1 ] = ll (C1[i].y + 0.5 );
127
+ res[i<< 1 | 1 ] = ll (C1[i].x + 0.5 );
128
128
}
129
- res.resize (n + m - 1 );
129
+ res.resize (n + m - 1 );
130
130
return res;
131
131
}
132
132
133
133
// arbitrary modulo convolution
134
- // n,m = degree + 1
135
- // x^2 + 2x +1 => n = 3
136
- void conv (int a[], int b[], int n, int m, int mod, int res[]) {
134
+ void conv (int a[], int b[], int n, int m, int mod, int res[]) {
137
135
int s = 1 , L = 0 ;
138
136
while (s <= n + m - 2 ) s <<= 1 , ++L;
139
- init (L);
137
+ init (L);
140
138
for (int i = 0 ; i < s; ++i) {
141
- A[i] = i < n ? Complex (a[i] / M, a[i] % M) : Complex ();
142
- B[i] = i < m ? Complex (b[i] / M, b[i] % M) : Complex ();
139
+ A[i] = i < n ? Complex (a[i] / M, a[i] % M) : Complex ();
140
+ B[i] = i < m ? Complex (b[i] / M, b[i] % M) : Complex ();
143
141
}
144
- trans (A, s, 1 );
145
- trans (B, s, 1 );
142
+ trans (A, s, 1 );
143
+ trans (B, s, 1 );
146
144
for (int i = 0 ; i < s; ++i) {
147
145
int j = i ? s - i : i;
148
- Complex a1 = (A[i] + A[j].conj ()) * Complex (0.5 , 0 );
149
- Complex a2 = (A[i] - A[j].conj ()) * Complex (0 , -0.5 );
150
- Complex b1 = (B[i] + B[j].conj ()) * Complex (0.5 , 0 );
151
- Complex b2 = (B[i] - B[j].conj ()) * Complex (0 , -0.5 );
146
+ Complex a1 = (A[i] + A[j].conj ()) * Complex (0.5 , 0 );
147
+ Complex a2 = (A[i] - A[j].conj ()) * Complex (0 , -0.5 );
148
+ Complex b1 = (B[i] + B[j].conj ()) * Complex (0.5 , 0 );
149
+ Complex b2 = (B[i] - B[j].conj ()) * Complex (0 , -0.5 );
152
150
Complex c11 = a1 * b1, c12 = a1 * b2;
153
151
Complex c21 = a2 * b1, c22 = a2 * b2;
154
- C1[j] = c11 + c12 * Complex (0 , 1 );
155
- C2[j] = c21 + c22 * Complex (0 , 1 );
152
+ C1[j] = c11 + c12 * Complex (0 , 1 );
153
+ C2[j] = c21 + c22 * Complex (0 , 1 );
156
154
}
157
- trans (C1, s, -1 );
158
- trans (C2, s, -1 );
155
+ trans (C1, s, -1 );
156
+ trans (C2, s, -1 );
159
157
for (int i = 0 ; i < n + m - 1 ; ++i) {
160
- int x = ll (C1[i].x + 0.5 ) % mod;
161
- int y1 = ll (C1[i].y + 0.5 ) % mod;
162
- int y2 = ll (C2[i].x + 0.5 ) % mod;
163
- int z = ll (C2[i].y + 0.5 ) % mod;
164
- res[i] = ((ll) x * M * M + (ll)(y1 + y2) * M + z) % mod;
158
+ int x = ll (C1[i].x + 0.5 ) % mod;
159
+ int y1 = ll (C1[i].y + 0.5 ) % mod;
160
+ int y2 = ll (C2[i].x + 0.5 ) % mod;
161
+ int z = ll (C2[i].y + 0.5 ) % mod;
162
+ res[i] = ((ll) x * M * M + (ll) (y1 + y2) * M + z) % mod;
165
163
}
166
164
}
167
165
}
0 commit comments