快速莫比乌斯变换

莫比乌斯变换

定义函数 f f f的莫比乌斯变换为 f ^ \hat f f^
f ^ S = ∑ T ⊆ S f T \hat f_S=\sum_{T\subseteq S}f_T f^S=TSfT
则有莫比乌斯反演
f S = ∑ T ⊆ S ( − 1 ) ∣ S ∣ − ∣ T ∣ f ^ T f_S=\sum_{T\subseteq S}(-1)^{|S|-|T|}\hat f_T fS=TS(1)STf^T

快速莫比乌斯变换FMT

考虑如何快速快速进行莫比乌斯变换和反演。

  • f ^ S i = ∑ T ⊆ S [ ( S − T ) ⊆ { 1 , 2 , . . . , i } ] f T \hat f_S^i=\sum\limits_{T \subseteq S} [(S - T) \subseteq \{1, 2, ..., i\}] f_{T} f^Si=TS[(ST){1,2,...,i}]fT
  • 易得初始状态: f ^ S 0 = f S \hat f_S^0 = f_{S} f^S0=fS { 1 , 2..0 } = ∅ \{1,2..0\}=\empty {1,2..0}=
  • 对于每一个不包含 { i } \{i\} {i}的集合 S S S,可知 f ^ S i = f ^ S i − 1 \hat f_S^i = \hat f_S^{i - 1} f^Si=f^Si1

f ^ S ∪ { i } i = ∑ T ⊆ S ∪ { i } [ ( S ∪ { i } − T ) ⊆ { 1 , 2 , . . . , i } ] f T \hat f_{S \cup \{i\}}^i=\sum\limits_{T \subseteq S\cup\{i\}} [(S\cup\{i\} - T) \subseteq \{1, 2, ..., i\}] f_{T} f^S{i}i=TS{i}[(S{i}T){1,2,...,i}]fT
其中 T T T可以分为一定包含 i i i和一定不包含 i i i两种情况。

  • 第一种情况 ( S ∪ { i } − T ) (S\cup\{i\} - T) (S{i}T)一定不包含 i i i,所以
    [ ( S ∪ { i } − T ) ⊆ { 1 , 2 , . . . , i } ] ⇔ [ ( S ∪ { i } − T ) ⊆ { 1 , 2 , . . . , i − 1 } ] [(S\cup\{i\} - T) \subseteq \{1, 2, ..., i\}]\Leftrightarrow[(S\cup\{i\} - T) \subseteq \{1, 2, ..., i-1\}] [(S{i}T){1,2,...,i}][(S{i}T){1,2,...,i1}]
    所以这部分的贡献为 f ^ S ∪ { i } i − 1 = ∑ T ⊆ S ∪ { i } [ ( S ∪ { i } − T ) ⊆ { 1 , 2 , . . . , i − 1 } ] f T \hat f_{S\cup\{i\}}^{i-1}=\sum\limits_{T\subseteq S\cup \{i\}}[(S\cup\{i\} - T) \subseteq \{1, 2, ..., i-1\}]f_T f^S{i}i1=TS{i}[(S{i}T){1,2,...,i1}]fT
  • 第二种情况
    T ⊆ S ∪ { i } ⇔ T ⊆ S [ ( S ∪ { i } − T ) ⊆ { 1 , 2 , . . . , i } ] [ ( S ∪ { i } − T − { i } ) ⊆ { 1 , 2 , . . . , i } − { i } ] [ ( S − T ) ⊆ { 1 , 2 , . . . , i − 1 } ] \begin{aligned} T\subseteq S\cup\{i\}&\Leftrightarrow T\subseteq S\\ [(S\cup\{i\} - T)&\subseteq \{1, 2, ..., i\}]\\ [(S\cup\{i\} - T-\{i\})&\subseteq \{1, 2, ..., i\}-\{i\}]\\ [(S - T)&\subseteq \{1, 2, ..., i-1\}] \end{aligned} TS{i}[(S{i}T)[(S{i}T{i})[(ST)TS{1,2,...,i}]{1,2,...,i}{i}]{1,2,...,i1}]
    所以这部分贡献为 f ^ S i − 1 = ∑ T ⊆ S [ ( S − T ) ⊆ { 1 , 2 , . . . , i − 1 } ] f T \hat f_S^{i-1}=\sum\limits_{T\subseteq S}[(S - T)\subseteq \{1, 2, ..., i-1\}]f_T f^Si1=TS[(ST){1,2,...,i1}]fT

综上
f ^ S ∪ { i } i = f ^ S i − 1 + f ^ S ∪ { i } i − 1 \hat f_{S\cup\{i\}}^i=\hat f_S^{i-1}+\hat f_{S\cup\{i\}}^{i-1} f^S{i}i=f^Si1+f^S{i}i1
O ( n 2 n ) O(n2^n) O(n2n)递推即可,反演也可以用类似的方法分析,最后得到
f S ∪ { i } i = f S ∪ { i } i − 1 − f S i − 1 f_{S\cup\{i\}}^i=f_{S\cup\{i\}}^{i-1}-f_S^{i-1} fS{i}i=fS{i}i1fSi1

void FMT(int *a,int n,int flag) {
    for(int i=0; i<n; i++)
        for(int j=0; j<(1<<n); j++)
            if(j>>i&1)
                a[j]=(a[j]+(flag+mod)%mod*a[j^(1<<i)]%mod)%mod;
}

应用

  1. 求集合的卷积 h = f ∗ g h=f*g h=fg h S = ∑ L ∪ R = S f L × g R h_S=\sum\limits_{L\cup R=S}f_L\times g_R hS=LR=SfL×gR
    h ^ S = ∑ T ⊆ S h T = ∑ T ⊆ S ∑ L ∪ R = T f L × g R = ∑ L ⊆ S ∑ R ⊆ S f L × g R = ∑ L ⊆ S f L ∑ R ⊆ S g R = f ^ S × g ^ S \begin{aligned} \hat h_S&=\sum_{T\subseteq S}h_T\\ &=\sum_{T\subseteq S}\sum_{L\cup R=T}f_L\times g_R\\ &=\sum_{L\subseteq S}\sum_{R\subseteq S}f_L\times g_R\\ &=\sum_{L\subseteq S}f_L\sum_{R\subseteq S}g_R\\ &=\hat f_S\times \hat g_S \end{aligned} h^S=TShT=TSLR=TfL×gR=LSRSfL×gR=LSfLRSgR=f^S×g^S

    F M T ( h ) = F M T ( f ) × F M T ( g ) FMT(h)=FMT(f)\times FMT(g) FMT(h)=FMT(f)×FMT(g)
    先对 f f f g g g进行快速莫比乌斯变换,然后对应项相乘,得到 h h h的莫比乌斯变换,然后进行莫比乌斯逆变换(反演),得到 h h h。形式和快速傅里叶变换一样。

  2. 另一种集合的卷积 h S = ∑ L ∪ R = S , L ∩ R = ∅ f L × g R h_S=\sum\limits_{L\cup R=S,L\cap R=\empty}f_L\times g_R hS=LR=S,LR=fL×gR
    F i , j = { f i , j ∣ j ∣ = i 0 ∣ j ∣ ≠ i F_{i,j}=\begin{cases} f_{i,j}\quad &|j|=i\\ 0\quad &|j|\neq i \end{cases} Fi,j={fi,j0j=ij=i i \quad i i是元素的个数, j j j是集合, ∣ j ∣ |j| j是集合 j j j的大小,同理 G i , j G_{i,j} Gi,j,那么 L ∩ R = ∅ ⇔ ∣ L ∣ + ∣ R ∣ = ∣ S ∣ L\cap R=\empty\Leftrightarrow |L|+|R|=|S| LR=L+R=S则有
    H i , j = ∑ i 1 + i 2 = i ∑ L ∪ R = j F i 1 , L × G i 2 , R H i = ∑ i 1 + i 2 = i F i 1 ∗ G i 2 ( 省 略 第 二 维 ) F M T ( H i ) = ∑ i 1 + i 2 = i F M T ( F i 1 ) × F M T ( G i 2 ) \begin{aligned} H_{i,j}&=\sum_{i_1+i_2=i}\sum_{L\cup R=j}F_{i_1,L}\times G_{i_2,R}\\ H_i&=\sum_{i_1+i_2=i}F_{i_1}*G_{i_2}\quad(省略第二维)\\ FMT(H_i)&=\sum_{i_1+i_2=i}FMT(F_{i_1})\times FMT(G_{i_2}) \end{aligned} Hi,jHiFMT(Hi)=i1+i2=iLR=jFi1,L×Gi2,R=i1+i2=iFi1Gi2()=i1+i2=iFMT(Fi1)×FMT(Gi2)
    最后要的答案就是满足 ∣ j ∣ = i |j|=i j=i H i , j H_{i,j} Hi,j
    例题

#include<bits/stdc++.h>
#define ll long long
#define mod 1000000009
using namespace std;
const int N=22;
int n,len,a[N][1<<N],b[N][1<<N],h[N][1<<N];
int ct(int x){
    return __builtin_popcount(x);
}
void FMT(int *a,int n,int flag) {
    for(int i=0; i<n; i++)
        for(int j=0; j<(1<<n); j++)
            if(j>>i&1)
                a[j]=(a[j]+(flag+mod)%mod*1ll*a[j^(1<<i)]%mod)%mod;
}
int main() {
    scanf("%d",&n);
    len=1<<n;
    for(int i=0;i<len;i++)
        scanf("%d",&a[ct(i)][i]);
    for(int i=0;i<len;i++)
        scanf("%d",&b[ct(i)][i]);
    for(int i=0;i<=n;i++)
        FMT(a[i],n,1),FMT(b[i],n,1);
    for(int i=0;i<=n;i++){
        for(int j=0;j<len;j++)
        for(int k=0;k<=i;k++)
        h[i][j]=(h[i][j]+1ll*a[k][j]*b[i-k][j]%mod)%mod;
        FMT(h[i],n,-1);
    }
    for(int i=0;i<len;i++)
        printf("%d ",h[ct(i)][i]);
    return 0;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值