首先,
&
,
∣
\&,|
&,∣ 卷积可以在 这里 找到
今天来说一说
⨂
\bigotimes
⨂ 卷积
问题:求 h k = ∑ i ⨂ j = k f j ∗ g k h_k=\sum_{i\bigotimes j=k} f_j*g_k hk=∑i⨂j=kfj∗gk,其中 ⨂ \bigotimes ⨂ 为不进位加法,在二进制中说的就是异或
首先我们有一个结论:
1 2 n ∑ T ( − 1 ) ∣ S ∩ T ∣ = [ S = ∅ ] \frac{1}{2^n}\sum_{T}(-1)^{|S\cap T|}=[S=\empty] 2n1T∑(−1)∣S∩T∣=[S=∅]
证明:当
S
=
∅
S=\empty
S=∅ 时,每一项的贡献都是
1
1
1
当
S
≠
∅
S\neq \empty
S=∅ 时,对于一个
a
∈
S
a\in S
a∈S
考虑
(
−
1
)
∣
S
∩
(
T
⊗
a
)
∣
=
(
−
1
)
(
∣
S
∩
T
)
⊗
a
=
−
(
−
1
)
∣
S
∩
T
∣
(-1)^{|S\cap (T\otimes a)|}=(-1)^{(|S\cap T)\otimes a}=-(-1)^{|S\cap T|}
(−1)∣S∩(T⊗a)∣=(−1)(∣S∩T)⊗a=−(−1)∣S∩T∣
所以有一一对应关系,于是上述式子为 0
考虑原式子
h
k
=
∑
i
∑
j
[
i
⊗
j
⊗
k
=
∅
]
f
i
∗
g
j
h_k=\sum_i\sum_j[i\otimes j\otimes k=\empty ]f_i*g_j
hk=i∑j∑[i⊗j⊗k=∅]fi∗gj
h
k
=
1
2
n
∑
i
∑
j
∑
T
(
−
1
)
∣
(
i
⊗
j
⊗
k
)
∩
T
∣
f
i
∗
g
j
h_k=\frac{1}{2^n}\sum_i\sum_j\sum_{T}(-1)^{|(i\otimes j\otimes k)\cap T|}f_i*g_j
hk=2n1i∑j∑T∑(−1)∣(i⊗j⊗k)∩T∣fi∗gj
注意到这里是可以拆出来的
h
k
=
1
2
n
∑
i
∑
j
∑
T
(
−
1
)
∣
i
∩
T
∣
(
−
1
)
∣
j
∩
T
∣
(
−
1
)
∣
k
∩
T
∣
f
i
∗
g
j
h_k=\frac{1}{2^n}\sum_i\sum_j\sum_{T}(-1)^{|i\cap T|}(-1)^{|j\cap T|}(-1)^{|k\cap T|}f_i*g_j
hk=2n1i∑j∑T∑(−1)∣i∩T∣(−1)∣j∩T∣(−1)∣k∩T∣fi∗gj
h
k
=
1
2
n
∑
T
(
−
1
)
∣
k
∩
T
∣
∑
i
(
−
1
)
∣
i
∩
T
∣
f
i
∑
j
(
−
1
)
∣
j
∩
T
∣
g
j
h_k=\frac{1}{2^n}\sum_{T}(-1)^{|k\cap T|}\sum_i(-1)^{|i\cap T|}f_i\sum_j(-1)^{|j\cap T|}g_j
hk=2n1T∑(−1)∣k∩T∣i∑(−1)∣i∩T∣fij∑(−1)∣j∩T∣gj
我们令
f
^
S
=
∑
T
(
−
1
)
∣
S
∩
T
∣
f
T
\hat f _S=\sum_{T}(-1)^{|S\cap T|}f_T
f^S=∑T(−1)∣S∩T∣fT,g 同理,那么有
h
k
=
1
2
n
∑
T
(
−
1
)
∣
k
∩
T
∣
f
^
T
∗
g
^
T
h_k=\frac{1}{2^n}\sum_{T}(-1)^{|k\cap T|}\hat f_T*\hat g_T
hk=2n1T∑(−1)∣k∩T∣f^T∗g^T
注意到如果有
h
^
k
=
∑
T
(
−
1
)
∣
k
∩
T
∣
h
T
\hat h_k=\sum_{T}(-1)^{|k\cap T|} h_T
h^k=T∑(−1)∣k∩T∣hT
那么就有
h
k
=
1
2
n
∑
T
(
−
1
)
∣
k
∩
T
∣
h
^
T
h_k=\frac{1}{2^n}\sum_{T}(-1)^{|k\cap T|}\hat h_T
hk=2n1T∑(−1)∣k∩T∣h^T
直接代入就可以证明
于是就有结论:
h
^
T
=
f
^
T
∗
g
^
T
\hat h_T=\hat f_T*\hat g_T
h^T=f^T∗g^T
可以快速实现 “点值” 的乘法
于是现在的问题就是快速求
f
^
k
=
∑
T
(
−
1
)
∣
k
∩
T
∣
f
T
\hat f_k=\sum_{T}(-1)^{|k\cap T|} f_T
f^k=T∑(−1)∣k∩T∣fT
我们按位从低到高来处理
令
f
(
i
)
f^{(i)}
f(i) 为考虑到第
i
i
i 位的时候的结果,那么容易得到
f
S
(
i
)
=
f
S
(
i
−
1
)
+
f
S
∪
{
i
}
(
i
−
1
)
f^{(i)}_S=f^{(i-1)}_S+f^{(i-1)}_{S\cup \{i\}}
fS(i)=fS(i−1)+fS∪{i}(i−1)
f
S
∪
{
i
}
(
i
)
=
f
S
(
i
−
1
)
−
f
S
∪
{
i
}
(
i
−
1
)
f^{(i)}_{S\cup \{i\}}=f^{(i-1)}_S-f^{(i-1)}_{S\cup \{i\}}
fS∪{i}(i)=fS(i−1)−fS∪{i}(i−1)
于是可以在
O
(
n
∗
2
n
)
O(n*2^n)
O(n∗2n) 的时间内实现
FWT 的另一种理解方式:
对于求 h k = ∑ i ⨂ j = k f j ∗ g k h_k=\sum_{i\bigotimes j=k} f_j*g_k hk=∑i⨂j=kfj∗gk,其中 ⨂ \bigotimes ⨂ 为不进位加法,是可以扩展到 k k k 进制的
我们考虑构造一个矩阵
A
A
A,满足
(
f
∗
A
)
∗
(
g
∗
A
)
=
(
h
∗
A
)
(f*A)*(g*A)=(h*A)
(f∗A)∗(g∗A)=(h∗A)
其中括号里面是向量乘矩阵,外面是向量的点乘
这样一来我们只需要对
f
,
g
f,g
f,g 进行变化,再乘上逆矩阵就可以了
不放令
x
=
(
x
0
x
1
.
.
.
x
m
)
k
x=(x_0x_1...x_m)_k
x=(x0x1...xm)k,令
x
′
x'
x′ 为
x
x
x 的最高位,
x
′
′
x''
x′′为
x
x
x 去掉最高位后剩下的
那么我们可以构造另一个矩阵
B
B
B,
s
.
t
.
A
x
,
y
=
∏
B
x
i
,
y
i
s.t. A_{x,y}=\prod B_{x_i,y_i}
s.t.Ax,y=∏Bxi,yi
考虑如果知道
B
B
B 如何求得
f
∗
A
f*A
f∗A
(
f
∗
A
)
[
x
]
=
∑
i
=
0
n
−
1
f
i
A
x
,
i
(f*A)[x]=\sum_{i=0}^{n-1}f_iA_{x,i}
(f∗A)[x]=i=0∑n−1fiAx,i
=
∑
p
=
0
k
−
1
B
x
′
,
p
∑
i
′
=
p
f
i
∗
A
x
′
′
,
i
′
′
=\sum_{p=0}^{k-1}B_{x',p}\sum_{i'=p}f_i*A_{x'',i''}
=p=0∑k−1Bx′,pi′=p∑fi∗Ax′′,i′′
后面一坨可以继续分治求下去
于是
B
B
B 需要满足的性质,有
∑
i
f
i
B
x
,
i
∑
j
g
j
B
x
,
j
=
∑
k
h
k
B
x
,
k
\sum_i f_iB_{x,i}\sum_jg_jB_{x,j}=\sum_kh_kB_{x,k}
i∑fiBx,ij∑gjBx,j=k∑hkBx,k
如果有
f
i
∗
g
j
∗
(
i
⊗
j
=
k
)
=
h
k
f_i*g_j*(i\otimes j=k)=h_k
fi∗gj∗(i⊗j=k)=hk,那么有
B
x
,
i
B
x
,
j
=
B
x
,
k
(
i
⊗
j
=
k
)
B_{x,i}B_{x,j}=B_{x,k}(i\otimes j=k)
Bx,iBx,j=Bx,k(i⊗j=k)
即
B
x
,
i
B
x
,
j
=
B
x
,
k
(
K
∣
i
+
j
−
k
)
B_{x,i}B_{x,j}=B_{x,k}(K|i+j-k)
Bx,iBx,j=Bx,k(K∣i+j−k)
B
=
1
1
1
.
.
.
1
w
K
1
w
K
2
.
.
.
1
w
K
2
w
K
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
w
K
K
−
1
w
K
2
∗
(
K
−
1
)
.
.
.
B=\begin{matrix} 1 & 1 & 1&... \\ 1 & w_K^1 & w_K^2 &...\\ 1 & w_K^2 & w_K^4 & ... \\ ... &...&...&...\\ 1 & w_K^{K-1} & w_K^{2*(K-1)} & ...\end{matrix}
B=111...11wK1wK2...wKK−11wK2wK4...wK2∗(K−1)...............
跟
f
f
t
fft
fft 的矩阵一样, 大概可以把
F
W
T
FWT
FWT 看做对每一位做了一遍循环卷积
二进制的时候:
B
=
1
1
1
−
1
B=\begin{matrix} 1 & 1 \\ 1 & -1 \end{matrix}
B=111−1
这符合我们之前的推论
子集卷积
h
k
=
∑
i
∑
j
[
i
∩
j
=
∅
]
[
i
∪
j
=
k
]
f
i
∗
g
j
h_k=\sum_{i}\sum_{j}[i\cap j=\empty][i\cup j=k]f_i*g_j
hk=i∑j∑[i∩j=∅][i∪j=k]fi∗gj
为了满足第一个限制,我们可以设置
n
n
n 个数组
第
i
i
i 个数组只有下标的
p
o
p
c
n
t
=
i
popcnt=i
popcnt=i 的地方才有值
然后我们为满足第二个限制对每一个做一遍
F
M
T
FMT
FMT,两两相乘,累加到对应的
p
o
p
c
n
t
popcnt
popcnt 数组中最后
I
F
M
T
IFMT
IFMT 回去,复杂度
O
(
n
2
∗
2
n
)
O(n^2*2^n)
O(n2∗2n)