LG P4717 【模板】快速莫比乌斯/沃尔什变换 (FMT/FWT)

\[C_k = \sum_{i|j=k}A_i B_j \]

这样的或卷积可以做一次 \(\text{FWT}\),把数组变为 \(\widehat{A}_i = \sum_{j\subseteq i}A_j\),也就是子集和的形式,然后就可以对应位相乘了
变回去的话就减掉之前加上来的贡献

与卷积,异或卷积同理
如果异或卷积只要求某一特定的次数 \(i\) 的系数,那么有 \([x^i]\widehat{A} = \sum_j [x^j]A \cdot {(-1)}^{\text{popcount(i&j)}}\)
而逆回去的话照上面的式子只要再多乘个 \(\frac1{2^{len}}\) 即可

$\text{Code}$
#include <cstdio>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define IN inline
using namespace std;

template <typename T>
IN void read(T &x) {
	x = 0; char ch = getchar(); int f = 0;
	for(; !isdigit(ch); f = (ch == '-' ? 1 : f), ch = getchar());
	for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar());
	if (f) x = ~x + 1;
}

typedef long long LL;
const int N = 2e5 + 5, P = 998244353, inv2 = (P + 1) >> 1;
int A[N], B[N], a[N], b[N], n;

IN void init(){for(int i = 0; i < n; i++) a[i] = A[i], b[i] = B[i];}
IN void print(){for(int i = 0; i < n; i++) printf("%d ", a[i]); puts("");}
IN void mul(){for(int i = 0; i < n; i++) a[i] = (LL)a[i] * b[i] % P;}

IN void FWT_or(int *a, int op) {
	for(int mid = 1; mid < n; mid <<= 1)
		for(int i = 0; i < n; i += (mid << 1))
			for(int j = 0; j < mid; ++j)
				(a[i + j + mid] += (LL)a[i + j] * op % P) %= P;
}
IN void FWT_and(int *a, int op) {
	for(int mid = 1; mid < n; mid <<= 1)
		for(int i = 0; i < n; i += (mid << 1))
			for(int j = 0; j < mid; ++j)
				(a[i + j] += (LL)a[i + j + mid] * op % P) %= P;
}
IN void FWT_xor(int *a, int op) {
	for(int mid = 1; mid < n; mid <<= 1)
		for(int i = 0; i < n; i += (mid << 1))
			for(int j = 0; j < mid; ++j) {
				int x = a[i + j], y = a[i + j + mid];
				a[i + j] = (LL)(x + y) * op % P,
				a[i + j + mid] = (LL)(x - y + P) * op % P;
			}
}


int main() {
	read(n), n = 1 << n;
	for(int i = 0; i < n; ++i) read(A[i]);
	for(int i = 0; i < n; ++i) read(B[i]);
	init(), FWT_or(a, 1), FWT_or(b, 1), mul(), FWT_or(a, P - 1), print();
	init(), FWT_and(a, 1), FWT_and(b, 1), mul(), FWT_and(a, P - 1), print();
	init(), FWT_xor(a, 1), FWT_xor(b, 1), mul(), FWT_xor(a, inv2), print();
}
posted @ 2022-11-07 19:21  leiyuanze  阅读(31)  评论(0编辑  收藏  举报