FWT 从入门到想死

位运算卷积。纯答辩。

高维前缀和

本质上是 OR 卷积。

https://www.cnblogs.com/heyuhhh/p/11585358.html

这个写得挺好。我觉得应该还算是很好理解吧?

位运算卷积

快速沃尔什变换 (FWT)

\(C_i=\sum\limits_{j\oplus k}A_jB_k\),则 \(C\)\(A,B\) 的位运算 \(\oplus\) 的卷积。

我们希望对 \(A,B,C\) 进行 FWT 取得 \(f(A),f(B),f(C)\),然后点积计算 \(f(C)=f(A)\cdot f(B)\),再对 \(f(C)\) 进行一次 IFWT 取得 \(C\) 以控制时间复杂度。

考虑构造 FWT 的变换方案。令 \(c(i,j)\) 表示 \(A_j\)\(f(A)_ i\) 的贡献系数那么有 \(f(A)_ i=\sum\limits_ {i=0}^{n-1} c(i,j)A_j\)。当然绝大多数 FWT 题都满足 \(n\)\(2\) 的幂次,否则不方便我们之后的操作。不过如果真的 \(n\neq 2^k\),其实在后面补足 \(0\) 就行了。

然后进行一个狠狠的等价变换:

\[\begin{aligned} f(C)_ i&=f(A)_ i\cdot f(B)_ i\\ \sum\limits_ {j=0}^{n-1} c(i,j)C_j&=[\sum\limits_ {j=0}^{n-1} c(i,j)A_j][\sum\limits_ {j=0}^{n-1} c(i,j)B_j]\\ \sum\limits_ {j=0}^{n-1} c(i,j)C_j&=\sum\limits_ {j=0}^{n-1}\sum\limits_ {k=0}^{n-1} c(i,j)c(i,k)A_jB_k\\ \end{aligned} \]

对左边根据定义式进行一个代换:\(C_ i=\sum\limits_{p\oplus q=i} A_pB_q\),那么有 \(f(C)_ i=\sum\limits_{j=0}^{n-1} c(i,j)\sum\limits_{p\oplus q=j} A_pB_q\)

回代,等价变换。鉴于 \(n\) 总是等于 \(2^k\),可以再更换枚举方式:

\[\begin{aligned} \sum\limits_{j=0}^{n-1} c(i,j)\sum\limits_{p\oplus q=j} A_pB_q &=\sum\limits_ {j=0}^{n-1}\sum\limits_ {k=0}^{n-1} c(i,j)c(i,k)A_jB_k\\ \sum\limits_{j=0}^{n-1}\sum\limits_{p\oplus q=j} c(i,p\oplus q)A_pB_q &=\sum\limits_ {j=0}^{n-1}\sum\limits_ {k=0}^{n-1} c(i,j)c(i,k)A_jB_k\\ \sum\limits_{p=0}^{n-1}\sum\limits_{q=0}^{n-1} c(i,p\oplus q)A_pB_q &=\sum\limits_ {j=0}^{n-1}\sum\limits_ {k=0}^{n-1} c(i,j)c(i,k)A_jB_k\\ \end{aligned} \]

统一字母,发现得到关系 \(c(i,j)c(i,k)=c(j\oplus k)\)。利用真值表和高中数学抽象函数求值的方法可以取得 \(c([0,1],[0,1])\) 也就是 \(c\) 函数的位矩阵。

为了方便之后分治卷积的操作并满足上述关系,我们考虑强行构造让 \(c(i,j)\) 的每一位都独立开,令 \(i_t\) 表示 \(i\) 二进制下第 \(t\) 位,\(j_t\) 表示 \(j\) 二进制下第 \(t\) 位,我们使 \(c(i,j)=\prod c(i_t,j_t)\)。回代可以发现,由于位矩阵早已满足关系,所以对于每个 \(t\) 都有 \(c(i_t,j_t)c(i_t,k_t)=c(i_t,j_t\oplus k_t)\),再把每一位合并在一起从而得到与 \(c(i,j)c(i,k)=c(i,j\oplus k)\) 等价。

假设我们已经取得了所有 \(c\),下一步就是猛算 \(f(A)_i=\sum\limits_{j=0}^{n-1} c(i,j)A_j\),当然这还是 \(\mathcal O(n^2)\) 的。

鉴于 \(n\) 总是等于 \(2^k\),考虑按二进制下最高位的值分治,再利用 \(c\) 每一位的独立性拆分进行变换:

\[\begin{aligned} f(A)_i&=\sum\limits_{j=0}^{n-1} c(i,j)A_j\\ &=[\sum\limits_{j=0}^{\frac{n}{2}-1} c(i,j)A_j]+[\sum\limits_{j=\frac{n}{2}}^{n-1} c(i,j)A_j]\\ &=[c(i_0,0)\sum\limits_{j=0}^{\frac{n}{2}-1} c(i',j')A_j]+[c(i_0,1)\sum\limits_{j=\frac{n}{2}}^{n-1} c(i',j')A_j]\\ \end{aligned} \]

很明显这里问题规模减半了,内部和式可以分治下去求。

考虑 \(A_0\) 表示前半部分的 \(A_j\) 组成的数列,\(A_1\) 表示后半部分的 \(A_j\) 组成的数列(注意下标从 \(0\) 而不是 \(\frac{n}{2}\) 开始),那么分类之后有:

  1. \(i_0=0\Rightarrow i'=i\),因为前半部分有最高位等于 \(0\),后半部分最高位等于 \(1\) 但下标改变于是 \(j'=j\Rightarrow f(A)_ i=c(0,0)f(A_0)_ i+c(0,1)f(A_1)_ i\)
  2. \(i_0=1\Rightarrow i'=i-\frac{n}{2}\),同上有 \(f(A)_ {i+\frac{n}{2}}=c(1,0)f(A_0)_ i+c(1,1)f(A_1)_ i\)

显然,\(i\in[0,\frac{n}{2})\)。显然可以使用 \(\mathcal O(n)\) 的代价合并两个问题,于是做到 \(\mathcal O(n\log n)\)。分治边界处取 \(f(A)_ i=A_i\)

求出 \(f(A)\)\(f(B)\) 后进行点积得到 \(f(C)\)

接下来考虑 IFWT,把 \(f(C)\) 反演回去。

快速沃尔什逆变换 (IFWT)

对位矩阵 \(c\) 进行肉眼矩阵求逆,得到一个新的位矩阵,这个矩阵就是 IFWT 的分治系数,其他部分与 FWT 没有区别。这也在构造的时候提出了严苛的要求:矩阵必须要有逆。一个有逆的矩阵需要满足不存在某一行或某一列全是 \(0\),万金油的构造(指 \(\left [ \begin{matrix} 1 & 1 \\ 1 & 1\\ \end{matrix} \right ]\))其实也是没有逆的。

肉眼矩阵求逆可以从 \(0\) 的位置入手,必要时可能需要列出方程。

\(f(C)\) 进行 IFWT 后得到的就是 \(C\) 的原数组了。

两条性质

FWT 本质上是线性变换,所以有 \(f(A+B)=f(A)+f(B)\)\(f(cA)=cf(A)\)(这里是点积)。

posted @ 2024-01-24 09:57  Shunpower  阅读(28)  评论(0编辑  收藏  举报