FWT

来自 luogu.com.cn/article/y0unggsj 以及题目题解

要解决的问题

\(C_k=\sum_{i\oplus j=k} A_iB_j\),其中 \(\oplus\) 是一种位运算。


目标:\(A\rightarrow \text{FWT}(A)\),算出 \(\text{FWT}(A)\cdot \text{FWT}(B)\),满足其等于 \(\text{FWT}(C)\),再逆变换回来。

\(\text{FWT}\) 应是线性变换。所以 \(\text{FWT}(A+B)=\text{FWT}(A)+\text{FWT}(B)\)\(\text{FWT}(cA)=c\text{FWT}(A)\)

\(c(i,j)\) 为变换系数,即 \(\text{FWT}(A)[i]=\sum_{j=0}^{n-1}c(i,j)A_j\)

因为 \(\text{FWT}(A)\cdot \text{FWT}(B)=\text{FWT}(C)\),所以 \(\text{FWT}(A)[i]\cdot \text{FWT}(B)[i]=\text{FWT}(C)[i]\)。即

\[\begin{aligned} \sum_{j=0}^{n-1}c(i,j)A_j\sum_{k=0}^{n-1}c(i,k)B_k=\sum_{l=0}^{n-1} c(i,l)C_l\\ \sum_{j=0}^{n-1}\sum_{k=0}^{n-1}c(i,j)c(i,k)A_jB_k=\sum_{l=0}^{n-1}c(i,l)C_l \end{aligned} \]

因为有 \(C_l=\sum_{j\oplus k=l}A_jB_k\),所以

\[\begin{aligned} \sum_{j=0}^{n-1}\sum_{k=0}^{n-1}c(i,j)c(i,k)A_jB_k=\sum_{l=0}^{n-1}c(i,l)\sum_{j\oplus k=l}A_jB_k \end{aligned} \]

右边从固定 \(l\) 变成枚举 \(j,k\)

\[\begin{aligned} \sum_{j=0}^{n-1}\sum_{k=0}^{n-1}c(i,j)c(i,k)A_jB_k=\sum_{j=0}^{n-1}\sum_{k=0}^{n-1}A_jB_kc(i,j\oplus k)。 \end{aligned} \]

所以,\(c(i,j)c(i,k)=c(i,j\oplus k)\)

一位一位考虑,令 \(c(i,j)=c(i_0,j_0)c(i_1,j_1)\cdots c(i_k,j_k)\),那么只需要 \(c([0,1],[0,1])\) 知道就好了。


按位或

相当于按位取 \(\max\)

\(c(i,j)c(i,j)=c(i,j|j)=c(i,j)\),所以 \(c(i,j)\in \{0,1\}\)

\(c(x,y)c(x,z)=c(x,\max(y,z))\),如果 \(c(x,y)=1\)\(c(x,z)=0\),则 \(c(x,y)c(x,z)=0=c(x,z)\),所以 \(y<z\)

所以一行中 \(1\)\(0\) 前面。

为了让矩阵

\[c = \begin{bmatrix} c(0,0) & c(0,1) \\ c(1,0) & c(1,1) \end{bmatrix} \]

有逆,所以矩阵满秩,所以不能有行是相同的。

那么每行 \(1\) 的个数正好就是 \(1,2,\cdots ,n\)

所以得到 \(\begin{bmatrix}1 & 1 \\ 1 & 0\end{bmatrix}\) 或者 \(\begin{bmatrix}1 & 0 \\ 1 & 1\end{bmatrix}\)

使用第二个矩阵,得到逆矩阵 \(\begin{bmatrix}1 & 0 \\ -1 & 1\end{bmatrix}\)

按位与

相当于按位取 \(\min\)

\(c(x,y)c(x,z)=c(x,\min(y,z))\),如果 \(c(x,y)=1\)\(c(x,z)=0\),则 \(c(x,y)c(x,z)=0=c(x,z)\),所以 \(y>z\)

所以一行中 \(1\)\(0\) 后面。

所以得到 \(\begin{bmatrix}0 & 1 \\ 1 & 1\end{bmatrix}\) 或者 \(\begin{bmatrix}1 & 1 \\ 0 & 1\end{bmatrix}\)

使用第二个矩阵,得到逆矩阵 \(\begin{bmatrix}1 & -1 \\ 0 & 1\end{bmatrix}\)

按位异或

\(c(0,0)c(0,y)=c(0,y\oplus 0)=c(0,y)\)。所以 \(c(0,0)=1\)

\(c(1,1)c(1,1)=c(1,0)\),因为不能矩阵有一行都是 \(0\),所以 \(c(1,1),c(1,0)\neq 0\)

\(c(1,0)c(1,1)=c(1,1)\),所以 \(c(1,0)=1\),所以 \(c(1,1)\in \{-1,1\}\)

\(c(0,1)c(0,1)=c(0,0)\),所以 \(c(0,1)\in \{-1,1\}\)

  • 如果 \(c(0,1)=-1\),则 \(c(1,1)\neq c(0,1)\),所以 \(c(1,1)=1\)

  • 如果 \(c(0,1)=1\),则 \(c(1,1)=-1\)

所以得到 \(\begin{bmatrix}1 & -1 \\ 1 & 1\end{bmatrix}\) 或者 \(\begin{bmatrix}1 & 1 \\ 1 & -1\end{bmatrix}\)

使用第二个矩阵,得到逆矩阵 \(\begin{bmatrix}0.5 & 0.5 \\ 0.5 & -0.5\end{bmatrix}\)


我们有 \(\text{FWT}(A)[i]=\sum_{j=0}^{n-1}c(i,j)A_j\)

考虑优化,按位拆半:

\[\text{FWT}(A)[i]=\sum_{j=0}^{n/2-1}c(i,j)A_j+\sum_{j=n/2}^{n-1}c(i,j)A_j \]

\(i'\)\(i\) 去掉二进制首位的数。则

\[\begin{aligned} \text{FWT}(A)[i]&=\sum_{j=0}^{n/2-1}c(i_0,j_0)c(i',j')A_j+\sum_{j=n/2}^{n-1}c(i_0,j_0)c(i',j')A_j \\ &=c(i_0,0)\sum_{j=0}^{n/2-1}c(i',j')A_{j}+c(i_0,1)\sum_{j=n/2}^{n-1}c(i',j')A_{j} \end{aligned} \]

这个时候两半遍历的 \(i',j'\) 是相等的,所以可以将规模减半。设 \(A_0\) 为首位为 \(0\) 的部分,\(A_1\) 为首位为 \(1\) 的部分,则有

  • \(i_0=0\)\(\text{FWT}(A)[i]=c(0,0)\text{FWT}(A_0)[i]+c(0,1)\text{FWT}(A_1)[i]\)

  • \(i_0=1\)\(\text{FWT}(A)[i+n/2]=c(1,0)\text{FWT}(A_0)[i]+c(1,1)\text{FWT}(A_1)[i]\)

其中上面的 \(i\in [0,n/2)\)

\(n=2^m\),则复杂度 \(\mathcal{O}(m2^m)\)

void OR(ll *f,ll ty=1){
    for (int p=1; p<n; p*=2){
        for (int i=0; i<n; i+=p*2){
            for (int j=i; j<i+p; j++){
                ll x=f[j],y=f[j+p];
                f[j]=x;
                f[j+p]=(y+x*ty%mod)%mod;
            }
        }
    }
}
void AND(ll *f,ll ty=1){
    for (int p=1; p<n; p*=2){
        for (int i=0; i<n; i+=p*2){
            for (int j=i; j<i+p; j++){
                ll x=f[j],y=f[j+p];
                f[j]=(x+y*ty%mod)%mod;
                f[j+p]=y;
            }
        }
    }
}
void XOR(ll *f,ll ty=1){
    for (int p=1; p<n; p*=2){
        for (int i=0; i<n; i+=p*2){
            for (int j=i; j<i+p; j++){
                ll x=f[j],y=f[j+p];
                f[j]=(x+y)*ty%mod;
                f[j+p]=(x-y+mod)*ty%mod;
            }
        }
    }
}

CF 1119 H

第一个想法是令 \(F_i[a_i]=x,F_i[b_i]=y,F_i[c_i]=z\),然后计算一个 \(\prod F_i\)。但是这个太慢了。

发现 \(F_i\) 只有三个非零位置,所以可以得到 \(\text{FWT}(F_k)[i]=c(i,a_k)x+c(i,b_k)y+c(i,c_k)z\)

根据上面按位异或卷积的推导,把每一位的 \(c(\_,\_)\) 乘起来,得到 \(c(i,j)=(-1)^{|i\cap j|}\)

那么 \(\text{FWT}(F_k)[i]=(-1)^{|i\cap a_k|}x+(-1)^{|i\cap b_k|}y+(-1)^{|i\cap c_k|}z\)。那么 \(\text{IFWT}(\prod \text{FWT}(i))\) 就是答案。

一共有 \(8\)\(\{-1,1\}^3\) 的情况,为了简化可以考虑 $\text{FWT[i]}\gets \text{FWT}[i\oplus a_1\oplus a_2\cdots \oplus a_k] $,因为异或的自反性,所以 \(\{a_i,b_i,c_i\}\) 可以变成 \(\{0,b_i\oplus a_i,c_i\oplus a_i\}\)。那么只有 \(4\) 种了。(*)

如果我们知道 \(x+y+z,x+y-z,x-y+z,x-y-z\) 分别的方案数 \(c_1,c_2,c_3,c_4\)(注意是对于每一个 \(i\) 而言),就可以通过快速幂求出答案。直接很难求,所以列一些方程,找一些关系(**)

  • \(c_1+c_2+c_3+c_4=n\)
  • \(x=0,y=1,z=0\),那么 \(\text{FWT}(F_k)[i]=(-1)^{|i\cap b_k|}\)。考虑贡献,有 \(\sum_{k=1}^n \text{FWT}(F_k)[i]=(-1)^{|i\cap b_k|}=c_1+c_2-c_3-c_4\)。因为 \(\text{FWT}\) 是线性变换,所以 \(\sum_{k=1}^n \text{FWT}(F_k)=\text{FWT}(\sum_{k=1}^n F_k)\),也就是 \(F'[k]=\sum_{i=1}^n [b_i=k]\)\(\text{FWT}\)
  • 同理求出 \(c_1-c_2+c_3-c_4\)\(c_1-c_2-c_3+c_4\)(这个令 \(F_k[b_k\oplus c_k]=1\))。

解一个方程就好了。

(*)理论上 \(8\) 种的也可以,但是小巧思简化思维代码难度。

(**)很好的方法,如果无从下手就尝试找到关系式。

CF 2194 F2

F1 提示我们先从暴力开始。

很显然,设 \(f_{u,x}\) 为子树 \(u\),被切断的异或和是 \(x\) 的方案数,那么初始 \(f_{u,0}=1\)。发现 \(x\) 其实是 \(b\) 中的线性组合,所以只用考虑 \(b\) 构成的线性基中的数,设 \(k'\) 为线性基大小,那么 \(x\) 可以用一个 \(k'\) 位二进制数表示。

转移考虑合并子树和切断自己。第一种可以异或卷积,第二种考虑子树异或和 \(s_u\),那么 \(f_{u,s_u}\gets f_{u,s_u}+\sum f_{u,s_u\oplus b_i}\)

现在的复杂度是 \(\mathcal{O}(n4^{k'})\) 的。考虑优化。

考虑维护 \(\text{FWT}(f)\)。那么初始化 \(f_{u,0}=1\) 相当于 \(\text{FWT}(f_u)=[1]\times 2^{k'}\)。异或卷积就是点乘。

现在要计算 \(\sum f_{u,s_u\oplus b_i}\)。这里 \(s,b\) 已经是二进制数表示了。把这个看成 \(\sum f_{u,s_u\oplus b_i}\times 1\),那么构造 \(g\),使得 \(g_{b_i}=1\),其他等于 \(0\)。那么可以看成 \(\sum f_{u,s_u\oplus b_i}\times g_{b_i}=\sum_{i\oplus j=s_u}f_ig_j\)。可以求 \(\text{FWT}(g)\),然后算出 \(\text{FWT}(f\times g)=\text{FWT}(f)\times \text{FWT}(g)\)。那么 \(\text{IFWT}(f\times g)[s_u]\) 即为所求。(*)

注意到这里单点求值,直接可以 \(\mathcal{O}(2^{k'})\) 算出,即为

\[val=\frac{1}{2^{k'}}\sum_{i=0}^{2^{k'}}(-1)^{|i\cap s_u|}\text{FWT}[f\times g][i] \]

将其加到 \(f_{u,s_u}\) 上,相当于 \(\text{FWT}(f)[i]\gets \text{FWT}(f)[i]+(-1)^{|i\cap s_u|} val\)

(*)这种看成异或卷积形式,非常厉害。

posted @ 2026-06-24 14:10  _Iroha  阅读(15)  评论(0)    收藏  举报