loading

fwt 根本学不会

QOJ12334 Tritwise Mex

感觉算是传统的 fwt?

这题发现很难写出位矩阵,考虑回归本源:按位处理。从高位考虑到低位,假设题目要求 \(A\otimes B\),写一个递归表示处理问题规模 \(3^{n}\) 的问题,先定义 \(A_0=A[0:3^{n-1}-1],A_1=A[3^{n-1}:2\cdot 3^{n-1}-1],A_2=A[2\cdot 3^{n-1},3^n-1]\)\(B_0,B_1,B_2\) 同理。假设我们能求出 \(3^{n-1}\) 规模的问题,考虑枚举第 \(n\) 位的结果是多少,若为 0,则可以是 \((1,2),(2,2),(1,1),(2,1)\) 四种情况,我们可以得到 \(C_0=(A_1+A_2)\otimes(B_1+B_2)\),递归下去即可;我们如法炮制的写出剩下的式子:

\[C_1=(A_0+A_2)\otimes(B_0+B_2)-A_2\otimes B_2 \]

\[C_2=(A_0+A_1+A_2)\otimes(B_0+B_1+B_2)-C_0-C_1 \]

需要进行共 \(4\) 次递归,所以复杂度 \(O(4^n)\)

UOJ310 黎明前的巧克力

发现题目相当于要求计算所有满足集合内的数的异或值等于 0 的数的贡献之和,一个集合 \(S\) 的贡献系数为 \(2^{|S|}\)。相当于求异或卷积意义下的 \(\prod (1+2x^{a_i})\),我们可以把 \(n\) 个多项式做 FWT 后乘起来再 IFWT。当然这太慢了,考虑到只有这么几项,根据位矩阵可以得到 \(FWT_i=\sum_j f_j(-1)^{\operatorname{popcount}(i\& j)}\)\(f_j\) 是第 \(j\) 项系数。由于只有 \(0,a_i\) 两项有系数,而 \(0\) 与任何数与的结果都是 0,所以 \(FWT_i\) 要么是 \(3\) 要么是 \(-1\)。最终我们想拿出第 \(i\) 项的 \(FWT_i\) 之积,设这一项上的 \(3\) 数为 \(x\)\(-1\) 数为 \(y\),则最终的 \(FWT_i=3^{x}(-1)^y\),IFWT 回去即可。

现在考虑求 \(x,y\),显然有 \(x+y=n\),但这远远不够。你可能会考虑到它的实际意义:\((-1)^{\operatorname{popcount}(i\& j)}\),但这极难统计。脑筋急转弯一下,FWT 有个经典性质:FWT 之和等于和的 FWT,考虑把每一项的系数加起来做一个 FWT,则第 \(i\) 位的值等于 \(3x-y\),解一下即可。复杂度 \(O(n\log n)\)


从下面那道题可以看出,这个做法的本质是计算 \(-1\) 项的系数,即 \(\sum_i (-1)^{\operatorname{popcount}(0\& p)}+(-2)^{\operatorname{popcount}(a_i\& p)}\),前面那项必然为 \(1\),所以若后面的指数是偶数则贡献 \(3\),否则贡献 \(-1\)所以可能也不需要脑筋急转弯了?

所以如果我只令 \(f_{a_i}=1\),则可以得到 \(x-y\) 的值,然后应该也可以做了?(upd:还真行)

CF1119H Triple

黎明前的巧克力加强版。

先解决这个问题。假设我们已经把 \(a_i\) 变成 0 了,令 \(c_1,c_2,c_3,c_4\) 分别为 \(x+y+z,x+y-z,x-y+z,x-y-z\) 的数量,则还是显然有 \(c_1+c_2+c_3+c_4=n\)。考虑 \((-1)^{\operatorname{popcount}(b_i\& p)}\) 的贡献,如果我只令 \(y=1\),那么 \(FWT'_p=\sum_i (-1)^{\operatorname{popcount}(b_i\& p)}\),此时若原来的一个多项式 FWT 后结果为 \(x+y+z\)\(x+y-z\),则该多项式对 \(FWT'\) 的贡献就是 1,否则就是 -1。由此又可以拿出一个方程 \(c_1+c_2-c_3-c_4=FWT'_p\),同时如法炮制的拿出 \(c_1-c_2+c_3-c_4=FWT''_p=\sum_i (-1)^{\operatorname{popcount}(c_i\& p)}\),但这还是不够。我们考虑只令 \(f_{b_i\oplus c_i}=1\),由于 \((a\oplus b)\& p=(a\&p)\oplus(b\&p)\),所以 \(FWT'''_p=\sum_i (-1)^{\operatorname{popcount}(b_i\& p)}(-1)^{\operatorname{popcount}(c_i\& p)}\),此时 \(c_1,c_4\) 由于这两项符号相等所以有正贡献,剩下的有负贡献,得到 \(c_1-c_2-c_3+c_4=FWT'''_p\)

(当然,个人感觉如果同时令 \(f_{b_i}=1,f_{c_i}=1\) 最终得出 \(2c_1-2c_4=FWT'''_p\) 也是对的。)

把这个做法推广到一般问题,即若 \(F_i=\sum_{1\le j\le k} f_jx^{a_{i,j}}\),求 \(\prod F_i\) 在异或卷积意义下的每一项系数。你虽然能拿出所有方程,但你可能承受不住暴力高消的 \(O(2^{3k})\) 的复杂度(当然这题直接手算即可)。考虑进一步观察,枚举 \(S\),只令 \(f_{val_i(S)}=1\)(其中 \(val_i(S)=\oplus_{j\in S}a_{i,j},S\subseteq\{1,2,\cdots,k\}\),如果钦定 \(c_T\) 中第 \(i\) 项的系数是 \((-1)^{(T>>i)\&1}\),那么说明只有 \(S\) 中的项有贡献,且若这一位上是 \(0\) 则为正贡献,否则为负贡献。因此 \(c_T\) 的贡献系数其实是 \((-1)^{\operatorname{popcount}(S\&T)}\)

假设当前考虑第 \(p\) 位,展开式子得到 \(\sum_{1\le i\le n}(-1)^{\operatorname{popcount}(val_i(S)\& p)}=\sum_T (-1)^{\operatorname{popcount}(S\&T)}c_T\)。注意到右侧实际上等于 \([x^S]FWT(c)\),而左侧等于 \([x^p]FWT(A_S)\),其中 \(\forall 1\le i\le n,A_{S,val_i(S)}=1\),枚举 \(S\) 并求出所有 \(2^k\)\(A\) 并把它们都求一遍 FWT,然后之后枚举每一位先把 \(FWT(c)\) 拿出来然后跑 IFWT 即可。时间复杂度 \(O(nk2^k+2^{k+m}(m+k))\)\(m\) 表示 \(a_i\) 值域为 \([0,2^m)\)

P7930 [COCI 2021/2022 #1] Set

先找点合法点对的性质。把 123 变成 012,单考虑一位,发现当全相等时,这一位上的和是 3 的倍数;当各不相同时,一定是 012 各一个,所以这一位上的和也是 3 的倍数;再发现其他情况都不是 3 的倍数。若将序列看成三进制数,我们相当于要求三个数的每一位之和都是 3 的倍数,即三进制异或结果为 0。三进制异或的转移矩阵是 \(Z_{i,j}=\omega^{(i-1)(j-1)}\)\(\omega\) 是三次单位根,算重的情况随便搞搞就行。复杂度就是三进制 fwt 的复杂度。

P10104/QOJ5827 [GDKOI2023 提高组] 异或图

posted @ 2026-01-10 09:39  dcytrl  阅读(0)  评论(0)    收藏  举报