莫比乌斯变换
定义函数
f
f
f的莫比乌斯变换为
f
^
\hat f
f^
f
^
S
=
∑
T
⊆
S
f
T
\hat f_S=\sum_{T\subseteq S}f_T
f^S=T⊆S∑fT
则有莫比乌斯反演
f
S
=
∑
T
⊆
S
(
−
1
)
∣
S
∣
−
∣
T
∣
f
^
T
f_S=\sum_{T\subseteq S}(-1)^{|S|-|T|}\hat f_T
fS=T⊆S∑(−1)∣S∣−∣T∣f^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=T⊆S∑[(S−T)⊆{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^Si−1
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=T⊆S∪{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,...,i−1}]
所以这部分的贡献为 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}i−1=T⊆S∪{i}∑[(S∪{i}−T)⊆{1,2,...,i−1}]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} T⊆S∪{i}[(S∪{i}−T)[(S∪{i}−T−{i})[(S−T)⇔T⊆S⊆{1,2,...,i}]⊆{1,2,...,i}−{i}]⊆{1,2,...,i−1}]
所以这部分贡献为 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^Si−1=T⊆S∑[(S−T)⊆{1,2,...,i−1}]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^Si−1+f^S∪{i}i−1
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}i−1−fSi−1
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;
}
应用
-
求集合的卷积 h = f ∗ g h=f*g h=f∗g, h S = ∑ L ∪ R = S f L × g R h_S=\sum\limits_{L\cup R=S}f_L\times g_R hS=L∪R=S∑fL×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=T⊆S∑hT=T⊆S∑L∪R=T∑fL×gR=L⊆S∑R⊆S∑fL×gR=L⊆S∑fLR⊆S∑gR=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。形式和快速傅里叶变换一样。 -
另一种集合的卷积 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=L∪R=S,L∩R=∅∑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,j0∣j∣=i∣j∣=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| L∩R=∅⇔∣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=i∑L∪R=j∑Fi1,L×Gi2,R=i1+i2=i∑Fi1∗Gi2(省略第二维)=i1+i2=i∑FMT(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;
}