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);
posted on 2022-06-28 00:02  naiji  阅读(182)  评论(0编辑  收藏  举报