知识点简单总结——FWT(快速沃尔什变换),FST(快速子集变换)

知识点简单总结——FWT(快速沃尔什变换),FST(快速子集变换)

闲话

博客园的markdown也太傻逼了吧。

快速沃尔什变换

位运算卷积

形如 $ f[ i ] = \sum\limits_{ j \oplus k = i} g[ j ] * h[ k ] $ 的形式的式子。

正常计算是 $ n^{ 2 } $ 。

与运算卷积

众所周知有 $ ( i \& j ) == k \longleftrightarrow ( i \& k == k ) \& \& ( j \& k == k ) $ 。

考虑构造 $ F( i ) = \sum\limits_{ j \& i == i } f( j ) $ 。

由上述结论容易推导得 $ F( i ) = G( i ) * H( i ) $ 。

将 $ f $ 正变换为 $ F $ 的方法:

由于 $ F $ 为父集和,考虑从低到高对于每一位,每次考虑仅有这一位不同的两个数,将该位为1的元素加到对应只有该位不同为0的元素上。

逆变换则是按照相同顺序每次从某一位为0的元素减去该位对应为1的元素。

或运算卷积

上述结论对或运算依然成立即 $ ( i | j ) == k \longleftrightarrow ( i | k == k ) \& \& ( j | k == k ) $ 。

同样构造 $ F( i ) = \sum\limits_{ j | i == i } f( j ) $ 。

正变换与与运算相似,不过是为将该位为0的元素加到该位为1的元素上,逆变换反之。

异或运算卷积

有结论 $ bitcount( i \& k ) \oplus bitcount ( j \& k ) \text{的奇偶} == bitcount( ( i \oplus j ) \& k ) \text{的奇偶} $ 。

构造 $ F( i ) = \sum\limits_{j} ( -1 )^{ bitcount( j \& i ) } f( j ) $ ,借助上述结论证明。

正变换依然从低到高位考虑每一对仅有对应位不同的两个数,

仅用0和1进行与运算,只有 $ 1 \& 1 = 1 $ ,其余均为0,

也就是说只有这一种运算改变奇偶性。

所以每次变换有 $ a = a + b , b = a - b $ 。

逆运算重新计算回去就是 $ a = \frac{ a + b }{2} , b = \frac{ a - b }{2} $ 。

快速子集变换

在DP问题中经常会有 $ f[ i ] = \sum\limits_{ j \subseteq i } g[ j ] * h[ i - j ] $ 一类的式子。

直接枚举子集是 $ 3^{ n } $ 。

把上式转换为 $ f[ i ] = \sum\limits_{ j | k == i , j \& k == 0} g[ j ] * h[ k ] $ 。

为了避免集合相交,考虑增加一维变成 $ f[c][i] $ , $ c $ 代表集合大小( $ 1 $ 的个数),仅在对应正确集合大小的时候某一位才有值。

然后直接或卷积就好了。

k进制异或卷积

考虑在上述二进制异或卷积中所使用的运算

二进制异或相当于二进制下不进位加法。

二进制与相当于二进制下不进位乘法。

$ bitcount $ 也可以同理推论。

因此我们用这个定义将其扩展到k进制。

之后考虑二进制卷积中 $ -1 $ 的含义。

异或卷积这玩意是有点类似循环卷积的。

所以我们可以想到利用单位根。

用类似方法就能求出对应k进制下的变换。

或者证不明白直接背个简单结论就行了:

$ j $ 对 $ i $ 的正贡献为 $ f_{ i , j } = \omega_{ k }^{ ij } $ ,逆贡献为 $ f_{ i , j }^{ -1 } $ 。

posted @ 2020-07-25 10:47  RikukiIX  阅读(553)  评论(0编辑  收藏  举报