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

本文介绍了子集卷积的概念,包括或卷积、与卷积和异或卷积。通过转换思想,利用类似于FFT的方法,将子集卷积的复杂度降低到线性或对数级别。文中给出了详细的计算过程和代码示例,帮助理解并实现子集卷积的高效算法。
最低0.47元/天 解锁文章
1045

被折叠的 条评论
为什么被折叠?



