Zeta & Mobius Transform

· · 个人记录

参(chu)考(chu): 容斥原理与子集卷积(四)

因为一些原因,要回来继续填了 /fad

upd:这个可以代替正常 \text{FWT} 的三重循环,虽然常数小没有我也不知道。至少模板题是这样的。 套娃。

定义函数 f:2^V \to \mathbb{Z} ,其中 Vn 元集合, 2^VV 所有子集的集合
定义 \zeta 变换

(\zeta f)(X)=\sum_{Y \subseteq X} f(Y)

即子集函数和
定义集合映射 g:V \to V_i ,其中 V=\{1,2,3,\dotsb,n\}V_i=\{v_1,v_2,v_3,\dotsb,v_n\} ,且 v_i = \begin{cases}1 &\text{if } i \in V \\0 &\text{if } i \notin V\ \end{cases}
所以

(\zeta f)(x_1,\dotsb,x_n)=\sum_{y_1,\dotsb,y_n \in \{0,1\}} f(y_1,\dotsb,y_n)

其中

y_1 \le x_1,y_2 \le x_2, \dotsb , y_n \le x_n

这就是说,如果将集合 X 看作一个 n 位的二进制数,那么 \zeta(X) 也就是求得每一位都小于等于它的数个数

然后参照知乎文章,我们可以写出二进制下的转移:

\zeta_{i}(x_1,\dotsb,x_n)= \begin{cases}\zeta_{i-1}(x_1,\dotsb,x_n) &\text{if } x_j=0 \\\zeta_{i-1}(x_1,\dotsb,x_{j-1},0,x_{j+1},\dotsb,x_n)+\zeta_{i-1}(x_1,\dotsb,x_{j-1},1,x_{j+1},\dotsb,x_n) &\text{if } x_j=1 \end{cases}

应用见下文。

另有 μ 变换的定义:

(\mu f)(X)=\sum_{Y \subseteq X}(-1)^{|X \setminus Y|}f(Y)

f=1 时它就是容斥原理

2022.5.8 upd:
对于上面这句话解释一下:

如果

f(X)=\sum_{Y \subseteq X}g(Y)

g(X)=\sum_{Y \subseteq X}(-1)^{|X \setminus Y|}f(Y)

证明在上面的l1nk里(OI-Wiki

定义 \text{odd-negation} 变换为

(\sigma f)(X)=(-1)^{|X|}f(X)

那么有如下定理:

定理1

\zeta = \sigma \mu \sigma\,,\,\mu = \sigma \zeta \sigma.

变换优先级是从右往左。

定理2

$\text{Proof : }

定理1:

\zeta = \sigma \mu \sigma\,:

(\zeta f)(X)= \sum_{Y \subseteq X}f(Y)=\sum_{Y \subseteq X}(-1)^{2|X|}f(Y) =\sum_{Y \subseteq X}(-1)^{|X|+|X \setminus Y|+|Y|}f(Y) =\sigma (\sum_{Y \subseteq X} (-1)^{|Y|+|X \setminus Y|}f(Y)) =\sigma \mu ((-1)^{|X|}f(X)) =(\sigma \mu \sigma f)(X) \square.

\mu = \sigma \zeta \sigma\,:

(\mu f)(X)=\sum_{Y \subseteq X}(-1)^{|X \setminus Y|}f(Y)=\sum_{Y \subseteq X}(-1)^{|X|-|Y|}f(Y) =\sum_{Y \subseteq X}(-1)^{|X|-|Y|+2|Y|}f(Y)=\sum_{Y \subseteq X}(-1)^{|X|+|Y|}f(Y) =(-1)^{|X|}\sum_{Y \subseteq X}((-1)^{|Y|}f(Y)) =(\sigma \zeta \sigma f)(X) \square.

定理2:
暂时有一步没看懂。

上述DP柿子可以做到在 O(n\,2^n) 时间计算一个给定集合的子集函数和
具体实现:

vector<int> zeta(/*Full set*/);
for(int i=0;i<=/*Max pow*/;++i)
    for(int j=0;j<=/*Full set*/;++j)
        if(j&(1<<i))
            calc zeta[j] with zeta[j^(1<<i)]

注:在国内貌似更多地叫它高维前缀和或子集前缀和, \text{atcoder}\text{editorial} 称作 \text{fast zeta transform}

事实上,由上面 \text{Mobius Transform} 的定义可以知道求出了 \zeta 变换也就求出了 \mu 变换,所以它可以搞 \text{FMT} (大概明白怎么弄了,还没实现过。)

官方题解
人话翻译

在定义出 x \bigsqcup y 后,如果知道 \zeta \;Transform ,就会发现这是个套了层皮的变换
也就是把 y_i 的值从 \{0,1\} 变成了 \{0,1,2,3,4,5,6,7,8,9\}
更直白地讲,也就是从二进制 \zeta 变换变成了十进制上的 \zeta 变换
对于每个 A_i 统计答案即可

record

变换部分:

static const int lim=pow10(6)-1;
inline void done(){
    ri t=1;
    for(ri i(0);i<=5;++i){
        for(ri j(0);j<=lim;++j)
        if(((j/t)%10)!=9) zeta[j+t]+=zeta[j];
        t=(t<<3)+(t<<1);
    }
}

单独写了一个分析

(a \times 1)(x)=\sum_{d \mid x}a(d)

可以用这个求 Dirichlet Prefix Sum

record

筛出 1 \sim n 所有的质数后枚举每个质数,对 kp [kp \le n] 加上 zeta_{k}

这个题也是一道比较裸的 zeta 变换。
具体地,i \operatorname{or} j \le K 可以看作是先作一次 zeta 变换求每个 i 的子集最大/次大值后,对每个 i 的最大+次大取前缀 \max 获得。
那么也就不难写了。