FWT
FFT是加速加法卷积的一个方法.\(C_i=\sum_{j+k=i}A_j\times B_k\)
FWT是加速位运算卷积的方法.\(C_i=\sum_{j\bigoplus k=i}A_j\times B_k\)
$\bigoplus $可以表示&,| ^
//n表示pa,pb两个数组有有2^n个有效元素,下标[0,2^n-1]
int mod = 998244353;
void FWTor(int a[], int type)
{
int i, j, k;
for (i = 1; i <= n; i++)
for (j = 0; j < (1 << n); j += 1 << i)
for (k = 0; k < (1 << i - 1); k++)
(a[j | (1 << i - 1) | k] += (a[j | k] * type + mod) % mod) %= mod;
}
void FWTand(int a[], int type)
{
int i, j, k;
for (i = 1; i <= n; i++)
for (j = 0; j < (1 << n); j += 1 << i)
for (k = 0; k < (1 << i - 1); k++)
(a[j | k] += (a[j | (1 << i - 1) | k] * type + mod) % mod) %= mod;
}
void FWTxor(int a[], long long type)
{
int i, j, k, x, y;
for (i = 1; i <= n; i++)
for (j = 0; j < (1 << n); j += 1 << i)
for (k = 0; k < (1 << i - 1); k++)
x = (a[j | k] + a[j | (1 << i - 1) | k]) * type % mod,
y = (a[j | k] - a[j | (1 << i - 1) | k] + mod) * type % mod,
a[j | k] = x, a[j | (1 << i - 1) | k] = y;
}
//or
FWTor(pa, 1); FWTor(pb, 1);
for (int i = 0; i < (1 << n); i++)
pa[i] = (ll)pa[i] * pb[i] % mod;
FWTor(pa, -1);
//and
FWTand(pa, 1); FWTand(pb, 1);
for (int i = 0; i < (1 << n); i++)
pa[i] = (ll)pa[i] * pb[i] % mod;
FWTand(pa, -1);
//xor
FWTxor(pa, 1); FWTxor(pb, 1);
for (int i = 0; i < (1 << n); i++)
pa[i] = (ll)pa[i] * pb[i] % mod;
FWTxor(pa, (mod + 1) >> 1);