2024.11.20 闲话

我也是服了这个 FWT 题解区的击败分治了,根本不可写作 . 流毒全 OI.jpg

不多说了,感觉不如高维前缀和,和 vfk 原始论文的描述一样:

模板题的代码:

const int N = 114514, P = 998244353, iv2 = (P + 1) >> 1;
int n;
vector<int> fwt(vector<int> v, auto method)
{
	int n = __lg(v.size()); assert((1 << n) == v.size());
	for (int j=0; j<n; j++)
		for (int i=0; i<(1<<n); i++)
			if (i & (1 << j)) tie(v[i ^ (1 << j)], v[i]) = method(v[i ^ (1 << j)], v[i]);
	return v;
}
vector<int> hadamard(vector<int> a, vector<int> b)
{
	int n = a.size(); assert(a.size() == b.size());
	for (int i=0; i<n; i++) a[i] = 1ll * a[i] * b[i] % P;
	return a;
}
vector<int> a, b;
int main()
{
	scanf("%d", &n); n = 1 << n; a.resize(n); b.resize(n);
	for (int i=0; i<n; i++) scanf("%d", &a[i]);
	for (int i=0; i<n; i++) scanf("%d", &b[i]);
	auto OR   = [&](int x, int y){return make_pair(x, (x + y) % P);};
    auto IOR  = [&](int x, int y){return make_pair(x, (y - x) % P);};
    auto AND  = [&](int x, int y){return make_pair((x + y) % P, y);};
    auto IAND = [&](int x, int y){return make_pair((x - y) % P, y);};
    auto XOR  = [&](int x, int y){return make_pair((x + y) % P, (x - y) % P);};
    auto IXOR = [&](int x, int y){return make_pair(1ll * (x + y) * iv2 % P, 1ll * (x - y) * iv2 % P);};
    auto A = fwt(hadamard(fwt(a, OR), fwt(b, OR)), IOR);
    auto B = fwt(hadamard(fwt(a, AND), fwt(b, AND)), IAND);
    auto C = fwt(hadamard(fwt(a, XOR), fwt(b, XOR)), IXOR);
    for_each(A.begin(), A.end(), [&](int x){printf("%d ", (x + P) % P);}); puts("");
    for_each(B.begin(), B.end(), [&](int x){printf("%d ", (x + P) % P);}); puts("");
    for_each(C.begin(), C.end(), [&](int x){printf("%d ", (x + P) % P);}); puts("");
	return 0;
}

有人叫 FMT,可能应该是这个意思:高维前缀和写法是 FMT,分治写法是 FWT .

歌:mochimochi - TAK feat. 初音ミク .

posted @ 2024-11-20 09:00  Jijidawang  阅读(111)  评论(1编辑  收藏  举报
😅​