FWT 学习笔记

大致参考 OI-wiki,改进、补充了一些描述。

约定

  • \(\cup\) 是按位或。
  • \(\cap\) 是按位与。
  • \(\oplus\) 是按位异或。
  • \(\operatorname{merge}\) 是将两个数组首尾相接。
  • 无特殊说明的情况下,\(A + B\) 表示两个数组 \(A, B\) 对位相加。
  • 无特殊说明的情况下,\(A \cdot B\) 表示两个数组 \(A, B\) 对位相乘。
  • 无特殊说明的情况下,\(n\) 是数组长度,且为了方便,默认 \(n\) 是 \(2\) 的整数次幂,且默认 0-index。

我们要解决的问题

给出 \(A, B\),我们希望快速求出一下式子中的 \(C\),其中 \(\otimes\) 是一种二元位运算。

\[C_i = \sum_{j \otimes k = i} A_j B_k \]

参照 FFT 的思想,我们希望能够将 \(A, B\) 经过某种运算表示成 \(\operatorname{FWT}[A], \operatorname{FWT}[B]\),使得 \(\operatorname{FWT}[C] = \operatorname{FWT}[A] \cdot \operatorname{FWT}[B]\),再对 \(\operatorname{FWT}[C]\) 进行逆运算得到 \(C\)。

FWT - or

我们构造

\[\operatorname{FWT}[A]_i = \sum_{i \cup j = i}A_j \]

,即 \(A\) 的子集和,容易发现这里的 \(\operatorname{FWT}[A]\) 是一个线性变换,因此有

\[\operatorname{FWT}[A+B] = \operatorname{FWT}[A] + \operatorname{FWT}[B] \]

不难发现这个东西是满足我们期望 FWT 变换满足的性质的。具体如下:

\[\begin{align} \operatorname{FWT}[A]_i \operatorname{FWT}[B]_i &= \left( \sum_{i \cup j = i} A_j \right) \left( \sum_{i \cup k = i} B_k \right) \nonumber \\ &= \sum_{i \cup j = i} \sum_{i \cup k = i} A_j B_k \nonumber \\ &= \sum_{i \cup (j \cup k) = i} A_j B_k \nonumber \\ &= \sum_{i \cup (j \cup k) = i} C_{j \cup k} \nonumber \\ &= \operatorname{FWT}[C]_i \nonumber \end{align} \]

那么我们应该如何求解 \(\operatorname{FWT}[A]\) 呢?考虑分治。

将 \(A\) 按照最高位分类。令 \(A\) 前 \(\frac{n}{2}\) 个元素为 \(A_0\),后 \(\frac{n}{2}\) 个元素为 \(A_1\)。

由于 \(i\) 的子集一定是 \(i\) 超集的子集,所以 \(i\) 的子集和一定被包含在 \(i + \frac{n}{2}\) 这个位置的子集和中。

所以

\[\operatorname{FWT}[A] = \operatorname{merge}(\operatorname{FWT}[A_0], \operatorname{FWT}[A_0] + \operatorname{FWT}[A_1]) \]

可在 \(O(n \log n)\) 的时间内得到解决。

接下来考虑 FWT - or 的逆操作 \(\operatorname{UFWT}\),为了方便描述,我们假设 \(A' = \operatorname{FWT}[A]\)。

容易发现线性变换的逆也是线性变换。因此

\[\operatorname{UFWT}[A+B] = \operatorname{UFWT}[A] + \operatorname{UFWT}[B] \]

同理,\(A_0\) 就是它本身 \(\operatorname{FWT}\) 的 \(\operatorname{UFWT}\),而 \(A_1\) 的 \(\operatorname{FWT}\) 是 \(A_0\) 和 \(A_1\) 的 \(\operatorname{FWT}\) 之和。因此

\[\begin{align} A_1 &= \operatorname{UFWT}[A'_1 - A'_0] \nonumber \\ &= \operatorname{UFWT}[A'_1] - \operatorname{UFWT}[A'_0] \nonumber \end{align} \]

\[\operatorname{UFWT}[A'] = \operatorname{merge}(\operatorname{UFWT}[A' _0], \operatorname{UFWT}[A'_1] - \operatorname{UFWT}[A' _ 0]) \]

问题得到解决。

FWT - and

同理,构造 \(A\) 序列的超集和

\[\operatorname{FWT}[A]_i = \sum_{i \cap j = i}A_j \]

这个东西同样满足 \(\operatorname{FWT}\) 运算的性质。

\[\begin{align} \operatorname{FWT}[A]_i \operatorname{FWT}[B]_i &= \left( \sum_{i \cap j = i} A_j \right) \left( \sum_{i \cap k = i} B_k \right) \nonumber \\ &= \sum_{i \cap j = i} \sum_{i \cap k = i} A_j B_k \nonumber \\ &= \sum_{i \cap (j \cap k) = i} A_j B_k \nonumber \\ &= \sum_{i \cap (j \cap k) = i} C_{j \cap k} \nonumber \\ &= \operatorname{FWT}[C]_i \nonumber \end{align} \]

同样考虑分治,\(A_1\) 的超集一定是 \(A_0\) 的超集,因此

\[\operatorname{FWT}[A] = \operatorname{merge}(\operatorname{FWT}[A_0] + \operatorname{FWT}[A_1], \operatorname{FWT}[A_0]) \]

\[\operatorname{UFWT}[A'] = \operatorname{merge}(\operatorname{UFWT}[A' _0] - \operatorname{UFWT}[A' _1], \operatorname{UFWT}[A'_1]) \]

FWT - xor

异或卷积比较不一样。我们定义 \(x \circ y = \operatorname{popcount}(x \cap y) \bmod 2\)。

我们构造

\[\operatorname{FWT}[A]_i = \sum_{i \circ j = 0} A_j - \sum_{i \circ j = 1} A_j \]

首先关于 \(\circ\) 运算有一个结论:

\[(x \circ y) \oplus (x \circ z) = x \circ (y \oplus z) \]

显然只要对 \(2\) 位二进制数上式成立即可归纳证明上式。枚举 \(x, y, z\) 总共 \(8\) 种情况,这里不再赘述。

那么我们依然要证明我们的构造满足 \(\operatorname{FWT}\) 的性质。

\[\begin{align} \operatorname{FWT}[A]_i \operatorname{FWT}[B]_i &= \left(\sum_{i \circ j = 0} A_j - \sum_{i \circ j = 1} A_j\right)\left(\sum_{i \circ k = 0} B_k - \sum_{i \circ i = 1} B_k\right) \nonumber \\ &= \left(\sum_{i \circ j = 0} \sum_{i \circ k = 0} A_j B_k + \sum_{i \circ j = 1} \sum_{i \circ k = 1} A_j B_k\right) - \left(\sum_{i \circ j = 1} \sum_{i \circ k = 0} A_j B_k + \sum_{i \circ j = 0} \sum_{i \circ k = 1} A_j B_k\right)\nonumber \\ &= \sum_{(i \circ j) \oplus (i \circ k) = 0} A_j B_k - \sum_{(i \circ j) \oplus (i \circ k) = 1} A_j B_k \nonumber \\ &= \sum_{i \circ (j \oplus k) = 0} A_j B_k - \sum_{i \circ (j \oplus k) = 1} A_j B_k \nonumber \\ &= \sum_{i \circ (j \oplus k) = 0} C_{j \oplus k} - \sum_{i \circ (j \oplus k) = 1} C_{j \oplus k} \nonumber \\ &= \operatorname{FWT}[C]_i \nonumber \end{align} \]

那么怎么求 \(\operatorname{FWT}[A]\) 呢?仍然分治,将 \(A\) 按照最高位是 \(0\) 还是 \(1\) 分成 \(A_0, A_1\)。

那么考虑 \(\operatorname{FWT}[A]\) 的前半部分的某个 \(i\),我们要对所有 \(j\) 统计答案。

接下来假设 \(\operatorname{FWT}[A]_0\) 表示 \(\operatorname{FWT}[A]\) 的前半部分,\(\operatorname{FWT}[A]_1\) 表示 \(\operatorname{FWT}[A]\) 的后半部分。

那么如果 \(j\) 也在前半部分,那么递归下去就好了,也就是从 \(\operatorname{FWT}[A_0]\) 转移来。

如果 \(j\) 在后半部分,那么由于 \(i\) 的最高位是 \(0\),所以 \(j\) 的最高位对 \(i \circ j\) 无影响。所以我们可以假定 \(i\) 的最高位是 \(1\),贡献就是后半部分的 \(j\) 对后半部分 \(i\) 的影响,也就是 \(\operatorname{FWT}[A_1]\)。所以

\[\operatorname{FWT}[A]_0 = \operatorname{FWT}[A_0] + \operatorname{FWT} [A_1] \]

接下来考虑 \(i\) 在后半部分的情况。同上考虑一个 \(j\) 的影响。

如果 \(j\) 在前半部分,那么 \(j\) 最高位是 \(0\),\(i \circ j\) 和 \(i\) 的最高位没有关系。所以有一个 \(\operatorname{FWT}[A_0]\)。

如果 \(j\) 在后半部分,那么 \(i \cap j\) 的最高位是 \(1\),\(\operatorname{popcount}\) 会增加 \(1\),也就是 \(i \circ j\) 会取反。所以会贡献 \(- \operatorname{FWT}[A_1]\)。因此

\[\operatorname{FWT}[A]_1 = \operatorname{FWT}[A_0] - \operatorname{FWT}[A_1] \]

综上所述,

\[\operatorname{FWT}[A] = \operatorname{merge}(\operatorname{FWT}[A_0] + \operatorname{FWT} [A_1], \operatorname{FWT}[A_0] - \operatorname{FWT}[A_1]) \]

接下来考虑 \(\operatorname{UFWT}\)。

假设 \(\operatorname{FWT}[A] = A'\)。那么 \(\operatorname{FWT}[A]_0 = A'_0\),\(\operatorname{FWT}[A]_1 = A'_1\)。

\[\begin{gather} \operatorname{FWT}[A]_0 = \operatorname{FWT}[A_0] + \operatorname{FWT} [A_1] \nonumber \\ \operatorname{FWT}[A]_1 = \operatorname{FWT}[A_0] - \operatorname{FWT}[A_1] \nonumber \end{gather} \]

由以上方程组,我们可以解得

\[\begin{gather} \operatorname{FWT}[A_0] = \frac{\operatorname{FWT}[A]_0 + \operatorname{FWT}[A]_1}{2} \nonumber \\ \operatorname{FWT}[A_1] = \frac{\operatorname{FWT}[A]_0 - \operatorname{FWT}[A]_1}{2} \nonumber \end{gather} \]

两个式子两边同时取 \(\operatorname{UFWT}\):

\[\begin{gather} A_0 = \frac{\operatorname{UFWT}[A'_0] + \operatorname{UFWT}[A'_1]}{2} \nonumber \\ A_1 = \frac{\operatorname{UFWT}[A'_0] - \operatorname{UFWT}[A'_1]}{2} \nonumber \end{gather} \]

\(\operatorname{merge}\) 一下,就可以得到 \(A'\) 的 \(\operatorname{UFWT}\)。

综上所述

\[\operatorname{FWT}[A] = \operatorname{merge}(\operatorname{FWT}[A_0] + \operatorname{FWT} [A_1], \operatorname{FWT}[A_0] - \operatorname{FWT}[A_1]) \]

\[\operatorname{UFWT}[A'] = \operatorname{merge} \left( \frac{\operatorname{UFWT}[A'_0] + \operatorname{UFWT}[A'_1]}{2}, \frac{\operatorname{UFWT}[A'_0] - \operatorname{UFWT}[A'_1]}{2} \right) \]

一些例题

P6097 【模板】子集卷积

求 \(c(S) = \sum \limits_{T \subseteq S} a(T) b(S \setminus T)\)。

所求即为

\[c(S) = \sum_{A \cup B = S \land A \cap B = \varnothing} a(A)b(B) \]

\(A \cup B = S\) 是一个 or 卷积的形式,可以直接 FWT。但是我们还额外限制了 \(A \cap B = \varnothing\)。

容易发现 \(A \cap B = \varnothing\) 等价于 \(|A \cup B| = |A| + |B|\)。所以我们考虑记录一个 \(c_{i, S}\) 满足

\[c_{i, S} = \sum_{A \cup B = S \land |A| + |B| = i} a(A)b(B) \]

同时假设 \(a_{i, S}, b_{i, S}\) 表示 \(a\) 中或 \(b\) 中仅有满足 \(\boldsymbol {|S| = i}\) 的位置不赋为 \(\boldsymbol 0\) 形成的序列。那么可以背包:

\[c_{i+j} = a_i * b_j \]

\(*\) 是 or 卷积,即可。

复杂度为 \(O(n^2 2^n)\)。

P13275 [NOI2025] 集合

首先要知道一个东西:\([P = Q]\) 怎么容斥。

\[\begin{align} [P = Q] &= \prod_{i = 0}^{n - 1}[P_i = Q_i] \nonumber \\ &= \prod_{i = 0}^{n-1} \left(2P_iQ_i - P_i - Q_i + 1\right) \nonumber \end{align} \]

考虑括号中的组合意义:如果都为 \(0\) 系数为 \(1\),如果都为 \(1\) 系数为 \(2\),如果一个 \(0\) 一个 \(1\) 系数为 \(-1\),上面式子就是从这些系数中各选一个的方案数。

所以我们枚举 \(A \subseteq P \cap Q\),\(B \subseteq P \cap ([2^n] \setminus Q),C \subseteq Q \cap ([2^n] \setminus P)\)。

那么

\[\begin{align} &= \sum_{A, B, C}2^{|A|}(-1)^{|B|+|C|} \nonumber \end{align} \]

有一个 \(B \cap A, C \cap A \not = \varnothing\) 的限制很不牛。

考虑直接构造 \(S = A \cup B, T = A \cup C\)。显然 \((S, T)\) 和 \((A, B, C)\) 双射。

那么

\[\begin{align} &= \sum_{S \subseteq P \land T \subseteq Q}2^{|S \cap T|}(-1)^{|S|+|T| - 2|S \cap T|} \nonumber \\ &= \sum_{S \subseteq P \land T \subseteq Q}2^{|S \cap T|}(-1)^{|S|+|T|} \nonumber \end{align} \]

答案的式子形如

\[\sum_{S, T} (-1)^{|S|+|T|} 2^{|S \cap T|} \sum_{S \subseteq f(P)} \sum_{T \subseteq f(Q)} [P \cap Q = \varnothing] \prod_{i \isin P \cup Q} a_i \]

记 \(A_S\) 表示 \(S\) 的超集,那么 \(P \isin A_S, Q \isin A_T\)。则枚举 \(R = P \cup Q\)。对于 \(i\),如果 \(i \isin A_S \cap A_T\),则可贡献 \(2\) 种划分的方案。否则 \(i\) 被划分入 \(S\) 或 \(T\) 的方案是确定且唯一的。可进行如下变形:

\[\sum_{S, T} (-1)^{|S|+|T|} 2^{|S \cap T|} \sum_{S \subseteq f(P)} \sum_{R \subseteq A_S \cup A_T} \prod_{i \isin R} (1 + [i \isin A_s \cap A_T])a_i \]

直接分组

\[\begin{align} \sum_{S, T} (-1)^{|S|+|T|} 2^{|S \cap T|} \sum_{S \subseteq f(P)} \left(\sum_{R \subseteq A_S \cap A_T} \prod_{i \subseteq R} 2a_i\right)\left(\sum_{R \subseteq (A_S \cup A_T) \setminus (A_S \cap A_T)} \prod_{i \subseteq R} a_i\right) \end{align} \]

要计算如下结构

\[\sum_{R \subseteq M} \prod_{i \subseteq R} c_i \]

的值,考虑这东西的组合意义:你要干一件事情,有 \(|M|\) 个步骤。考虑 \(M\) 的一个元素 \(i\)。如果 \(i \isin R\),那么完成这一步有 \(c_i\) 种方案;否则有 \(1\) 种方案。容易发现一个步骤总共有 \(c_i + 1\) 种方案,且步骤之间是独立的。

\[\sum_{R \subseteq M} \prod_{i \subseteq R} c_i = \prod_{i \subseteq M} (c_i + 1) \]

接下来把这个东西代回 \((1)\) 式。

\[\sum_{S, T} (-1)^{|S|+|T|} 2^{|S \cap T|} \sum_{S \subseteq f(P)} \left(\prod_{i \subseteq A_S \cap A_T} (2a_i+1)\right)\left(\prod_{i \subseteq (A_S \cup A_T) \setminus (A_S \cap A_T)} (a_i+1)\right) \]

注意到 \(i \subseteq A_S \cap A_T\) 也就是在说 \((S \cup T) \subseteq i\),\(i \subseteq A_S \cup A_T\) 就是 \(S \subseteq i\) 或者 \(T \subseteq i\)。但是 \(i \subseteq (A_S \cup A_T) \setminus (A_S \cap A_T)\) 的限制很不牛。事实上我们可以先不管 \(i \subsetneq (A_S \cap A_T)\) 的限制,把这些多余的贡献也乘进去。然后我们在处理 \(i \subseteq A_S \cap A_T\) 的时候,把多算的 \((a_i + 1)^2\) 除掉。所以 \((1)\) 式还可以改写成

\[\sum_{S, T} (-1)^{|S|+|T|} 2^{|S \cap T|} \left(\prod_{S \subseteq R} (a_R + 1)\right)\left(\prod_{T \subseteq R} (a_R + 1)\right)\left(\prod_{(S \cup T) \subseteq R} \frac{2a_R + 1}{(a_R+1)^2}\right) \]

注意到 \(|S \cap T| = |S| + |T| - |S \cup T|\)。考虑把 \(2\) 的次数拆开,可以得到

\[\begin{align} &= \sum_{S, T} (-1)^{|S|+|T|} 2^{|S| + |T| - |S \cup T|} \left(\prod_{S \subseteq R} (a_R + 1)\right)\left(\prod_{T \subseteq R} (a_R + 1)\right)\left(\prod_{(S \cup T) \subseteq R} \frac{2a_R + 1}{(a_R+1)^2}\right) \nonumber \\ &= \sum_{S, T} \left((-2)^{|S|}\prod_{S \subseteq R} (a_R + 1)\right)\left((-2)^{|T|}\prod_{T \subseteq R} (a_R + 1)\right)\left(2^{-|S \cup T|}\prod_{(S \cup T) \subseteq R} \frac{2a_R + 1}{(a_R+1)^2}\right) \nonumber \end{align} \]

那么我们可以处理出

\[\begin{gather} f_S = (-2)^{|S|}\prod_{S \subseteq R} (a_R + 1) \nonumber \\ g_S = 2^{-|S|}\prod_{S \subseteq R} \frac{2a_R + 1}{(a_R+1)^2} \nonumber \end{gather} \]

所求即为

\[\sum_{S, T} f_S f_T g_{S \cup T} \]

考虑 \(h = f * f\)(or 卷积),那么答案就是

\[\sum_{R} h_R g_R \]

\(f, g\) 可以一遍高维后缀积求出;\(h\) 可以一次 FWT 求出。那么这个题就做完了。由于涉及到 \(\times 0 / 0\) 运算,需要手写 modint。

复杂度 \(O(n 2^n)\)。

posted @ 2026-03-06 09:37  dyc2022  阅读(26)  评论(0)    收藏  举报
/* 设置动态特效 */ /* 设置文章评论功能 */ 返回顶端 levels of contents