莫比乌斯变换&子集卷积

今天学习莫比乌斯变换。

大佬の博客

前置技能

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

干嘛用的?

用来快速计算子集卷积。
就是说,
f[i]=g[j]h[k](jk=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)f[i]=\sum {g[j]*h[k]}{(j|k=i)}
我们定义f1[i]表示所有i的子集的和。
不如直接看图算了。.

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

所以呢?

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

怎么办?

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

怎么反演?

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