前言
子集卷积,指的是 c i = ∑ j ⊕ k = i a j × b k c_i=\sum\limits_{j\oplus k=i}a_j\times b_k ci=j⊕k=i∑aj×bk,其中 ⊕ \oplus ⊕ 指的是 ∪ , ∩ , x o r \cup,\cap,xor ∪,∩,xor。
在这里,把 i , j , k i,j,k i,j,k 的二进制看作集合。
或卷积
现在我们先求 c i = ∑ j ∪ k = i a j × b k c_i=\sum\limits_{j\cup k = i}a_j\times b_k ci=j∪k=i∑aj×bk。
朴素的求法是 O ( n 2 ) O(n^2) O(n2) 的。
我们回忆 F F T FFT FFT 是怎么加速卷积过程的。 F F T FFT FFT 是快速得到多项式的一个点值表示,其实是找到一种变换,满足 C i ′ = A i ′ × B i ′ C'_i=A'_i\times B'_i Ci′=Ai′×Bi′,让它能够在 O ( n ) O(n) O(n) 的时间内得到 C C C 的点值表示。
在这里,我们也用这个思想。不妨令 A ′ A' A′ 表示 A A A 的变换。
注意到(我也不知道怎么想出来的),当 a i ′ = ∑ j ⊆ i a j a'_i=\sum\limits_{j\subseteq i}a_j ai′=j⊆i∑aj, c i ′ = a i ′ × b i ′ c'_i=a'_i\times b'_i ci′=ai′×bi′。
a i ′ a'_i ai′ 其实就是子集和。我们稍微证明一下。
c i ′ = ∑ d ⊆ i c d = ∑ d ⊆ i ∑ j ∪ k = d a j × b k = ∑ j ∪ i , k ∪ i a j × b k = ( ∑ j ∪ i a j ) × ( ∑ k ∪ i b k ) = a i ′ × b i ′ c'_i=\sum\limits_{d\subseteq i}c_d=\sum\limits_{d\subseteq i}\sum\limits_{j\cup k=d}a_j\times b_k=\sum\limits_{j\cup i,k\cup i}a_j\times b_k=(\sum\limits_{j\cup i}a_j)\times(\sum\limits_{k\cup i}b_k)=a'_i\times b'_i ci′=d⊆i∑cd=d⊆i