集合幂级数

子集卷积

只有 \(i\cup j=k\) 的限制,我们已经会做了,难点在于 \(i\cap j=0\) 的限制。

发现 \(i\cap j=0\),相当于 \(|i|+|j|=|i\cup j|\)。那么可以再开一维记录 \(|S|\)

\(f_{i,j}=[|j|=i]a_j\)\(g_{i,j}=[|j|=i]b_j\),那么 \(h_i=\sum_{k=0}^i f_k*g_{i-k}\) 就是答案(\(*\) 是点乘)。

\(c_i=h_{|i|,i}\)

for (int i=0; i<21; i++){
    fwt(f[i]),fwt(g[i]);
}
for (int i=0; i<21; i++){
    for (int j=0; j<(1<<n); j++){
        for (int k=0; k<=i; k++){
            h[i][j]=(h[i][j]+f[k][j]*g[i-k][j]%mod)%mod;
        }
    }
    ifwt(h[i]);
}
for (int i=0; i<(1<<n); i++){
    cout<<h[ppc(i)][i]<<" ";
}

集合幂级数

\(F\) 上的集合幂级数 \(f\)\(2^U\rightarrow F\) 的函数,平常表示为 \(f=\sum_{S\in 2^U} f_Sx^S\)\(x^S\) 作为一个占位符,其中 \(S\) 可以是集合的二进制表示。

看上去和形式幂级数很像。

加法:\(h=f+g\),则 \(h_S=f_S+g_S\)

乘法:\(h=f\cdot g=\sum_{L\in 2^U}\sum_{R\in 2^U}f_Lx^L\cdot g_Lx^R\)。其中 \(x^L\cdot x^R=x^{L\oplus R}\),其中 \(\oplus\) 是位运算。其满足有分配律,交换律,结合律。

集合幂级数 \(\exp\)

同样的,设 \([x^Sy^i]F(x,y)=[x^S]F(x)\times [|S|=i]\),和子集卷积一样。

\(x\) 维上 \(\text{FWT}\),可以使不同的 \(S\) 之间独立,故而转为 \(g(y)=e^{f(y)}\) 的多项式 \(\exp\)

求导可知 \(g'(y)=e^{f(y)}f'(y)=g(y)f'(y)\)

所以 \([y^n]g'(y)=\sum_{i=0}^n [y^{n-i}]g(y)\times [y^i]f'(y)\)。熟知 \((x^{n+1})'=(n+1)x^n\),可以整理得到 \([y^n]g(y)=\frac{1}{n}\sum_{i=1}^n [y^{n-i}]g(y)\times i[y^i]f(y)\)

(*)这个方法的本质是什么?求导可以使得多项式从 \([y^n]\) 变成 \((n+1)[y^{n+1}]\),相当于不会出现“自我贡献”,从而可以递推求解。求导是一种将次,也可以说是一种升次。

for (int i=0; i<21; i++){
    fwt(f[i]);
}
for (int i=0; i<(1<<n); i++){
    g[0][i]=1;
}
for (int i=1; i<21; i++){
    ll iv=pw(i,mod-2);
    for (int j=0; j<(1<<n); j++){
        for (int k=1; k<=i; k++){
            g[i][j]=(g[i][j]+g[i-k][j]*f[k][j]%mod*k)%mod; 
        }
        g[i][j]=g[i][j]*iv%mod;
    }
}	
for (int i=0; i<21; i++){
    ifwt(g[i]);
}

其实可以看出,这个和子集卷积的代码很相像。

集合幂级数 \(\exp\)(非素数模数)

题目中给定

\[e^{F(x)}=\sum_{n\ge 0}\frac{F^n(x)}{n!} \]

可以发现他其实等于

\[\sum_{\bigcup S_k=S,\sum |S_k|=|S|} \prod a_{S_i} \]

那么 \([x^S]e^{F(x)}\) 相当于划分 \(S\) 的权值和,权值定义为 \([x^{S_k}]F(x)\) 的积,并且那么是无序的。组合意义可知必定满足 \([x^{\varnothing}]F(x)=0\)

因为是无序的,所以钦定一个顺序:从大到小。设 \(S\) 最大元为 \(u\),枚举 \(u\in T\),那么

\[[x^S]e^{F(x)}=\sum_{T\subseteq S,u\in T} [x^T]F(x)\times [x^{S\setminus T}]e^{F(x)} \]

从小到大枚举 \(u\)(因为大的 \(u\) 由小的 \(u\) 递推而来)。发现把 \(u\) 去掉不管,剩下的做子集卷积,最后再位移 \(2^{u-1}\) 即可。

具体的,设 \(S\setminus \{u\}=S'\)\(T\setminus \{u\}=T'\),那么相当于 \([x^{T'}]F(x)\times [x^{S'\setminus T'}]e^{F(x)}\rightarrow [x^{S'}]e^{F(x)}\)。把 \(e^{F(x)}\) 看作 \(g\),一样的操作。

g[0][0]=1;
for (int u=1; u<=n; u++){
    int cur=(1<<u-1);
    for (int j=1; j<=u; j++){
        fwt(f[j]+cur,u-1);
    }
    for (int j=0; j<u; j++){
        fwt(g[j],u-1);
    }
    for (int i=1; i<=u; i++){
        for (int j=0; j<=u-i; j++){
            for (int k=0; k<(1<<u-1); k++){
                g[i+j][k+cur]+=f[i][k+cur]*g[j][k];
            }
        }
    }
    for (int i=0; i<u; i++){
        ifwt(g[i],u-1);
    }
    for (int i=1; i<=u; i++){
        ifwt(g[i]+cur,u-1);
    }
}

注意这里的 +cur 相当于位移,因为 fwt 传入的是一个指针。

posted @ 2026-06-27 21:12  _Iroha  阅读(10)  评论(0)    收藏  举报