莫比乌斯变换&子集卷积

今天学习莫比乌斯变换。

大佬の博客

前置技能

fwt与运算。
其实就是这个的低配版本

干嘛用的?

用来快速计算子集卷积。
就是说,
f [ i ] = ∑ g [ j ] ∗ h [ k ] ( j ∣ k = i & & j & k = 0 ) f[i]=\sum {g[j]*h[k]}{(j|k=i\&\&j\&k=0)} f[i]=g[j]h[k](jk=i&&j&k=0)

核心思想

打包运算。
首先我们考虑它的低配版本。
f [ i ] = ∑ g [ j ] ∗ h [ k ] ( j ∣ k = i ) f[i]=\sum {g[j]*h[k]}{(j|k=i)} f[i]=g[j]h[k](jk=i)
我们定义f1[i]表示所有i的子集的和。
不如直接看图算了。.

莫比乌斯变换&子集卷积_第1张图片
这样我们就实现了打包运算:h’[i]表示所有下标是i的子集的答案之和。

所以呢?

考虑我们算重了什么。
我们会把有交集的下标算进去,比如 2 & 3 = 2 2\&3=2 2&3=2实际上是不行的。

怎么办?

统计位数。
令f[i][j]表示下标为i,i中有j个1的f的对应变换,即只考虑所有 p o p c o u n t ( i ) = = j popcount(i)==j popcount(i)==j的原f数组为对应值。
然后枚举两边的1个数,只有所有1的个数与下标实际1的个数相同的才会产生贡献。
(否则就是打包出锅了。)

怎么反演?

最后对于每个下标处相乘时多项式反演即可。
n 2 n^2 n2即可。
小朋友化式子法

你可能感兴趣的:(各类笔记)