-
Notifications
You must be signed in to change notification settings - Fork 109
/
Copy pathFast Walsh-Hadamard Transform.cpp
46 lines (45 loc) · 1.11 KB
/
Fast Walsh-Hadamard Transform.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
const int N = 1<<16;
template <typename T>
struct FWT {
void fwt(T io[], int n) {
for (int d = 1; d < n; d <<= 1) {
for (int i = 0, m = d<<1; i < n; i += m) {
for (int j = 0; j < d; j++) { /// Don't forget modulo if required
T x = io[i+j], y = io[i+j+d];
io[i+j] = (x+y), io[i+j+d] = (x-y); // xor
// io[i+j] = x+y; // and
// io[i+j+d] = x+y; // or
}
}
}
}
void ufwt(T io[], int n) {
for (int d = 1; d < n; d <<= 1) {
for (int i = 0, m = d<<1; i < n; i += m) {
for (int j = 0; j < d; j++) { /// Don't forget modulo if required
T x = io[i+j], y = io[i+j+d];
/// Modular inverse if required here
io[i+j] = (x+y)>>1, io[i+j+d] = (x-y)>>1; // xor
// io[i+j] = x-y; // and
// io[i+j+d] = y-x; // or
}
}
}
}
// a, b are two polynomials and n is size which is power of two
void convolution(T a[], T b[], int n) {
fwt(a, n);
fwt(b, n);
for (int i = 0; i < n; i++)
a[i] = a[i]*b[i];
ufwt(a, n);
}
// for a*a
void self_convolution(T a[], int n) {
fwt(a, n);
for (int i = 0; i < n; i++)
a[i] = a[i]*a[i];
ufwt(a, n);
}
};
FWT<ll> fwt;