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. 初音ミク .
以下是博客签名,正文无关
本文来自博客园,作者:Jijidawang,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/18556021
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ