集合幂级数

这篇博客介绍了集合幂级数、高维前缀和、后缀和、卷积、异或卷积以及子集卷积的概念和计算方法。重点讨论了快速莫比乌斯变换(FMT)、子集卷积的优化技巧以及多项式复合集合幂级数的求解过程,涉及复杂度分析和实际应用。
摘要由CSDN通过智能技术生成

定义

形如 ∑ i = 0 2 n − 1 a i x i \sum_{i=0}^{2^n-1}a_ix^i i=02n1aixi,其中 i i i 是一个二进制数,表示 { 1 , 2 , . . . , n } \{1,2,...,n\} {1,2,...,n} 的一个子集。



基本操作

高维前缀和

即要求: c i = ∑ j [ j ∨ i = i ] a j c_i=\sum_j[j∨i=i]a_j ci=j[ji=i]aj

先考虑一维前缀和:

for(int i=1;i<=n;i++) a[i]+=a[i-1];

然后考虑二维前缀和:

for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]+=a[i][j-1];
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]+=a[i-1][j];

以此类推,n维前缀和即为每次枚举一维,在这一维上做前缀和:

for(int i=0;i<n;i++)
	for(int j=0;j<(1<<n);j++)
		if(j&(1<<i)) a[j]+=a[j^(1<<i)];

这种做法即为 快速莫比乌斯变换,即FMT
复杂度为 O ( 2 n n ) O(2^nn) O(2nn)


高维后缀和

即要求: c i = ∑ j [ j ∧ i = i ] a j c_i=\sum_j[j∧i=i]a_j ci=j[ji=i]aj

与前缀和类似每次枚举一维做后缀和即可:

for(int i=0;i<n;i++)
	for(int j=0;j<(1<<n);j++)
		if(j&(1<<i)) a[j^(1<<i)]+=a[j];

或卷积

即要求: c i = ∑ j ∑ k [ j ∨ k = i ] a j b k c_i=\sum_j\sum_k[j∨k=i]a_jb_k ci=jk[jk=i]ajbk

a a a 经过 FMT 后的集合幂级数为 A A A b b b 经过 FMT 后的集合幂级数为 B B B c c c 经过 FMT 后的集合幂级数为 C C C,容易发现 C i = A i B i C_i=A_iB_i Ci=AiBi

所以我们只需要对 a , b a,b a,b 分别做一次 FMT ,并将对应位相乘后做一次 FMT 的逆变换,即将刚才的过程反过来:

for(int i=0;i<n;i++)
	for(int j=0;j<(1<<n);j++)
		if(j&(1<<i)) a[j]-=a[j^(1<<i)];

复杂度为 O ( 2 n n ) O(2^nn) O(2nn)


与卷积

即要求: c i = ∑ j ∑ k [ j ∧ k = i ] a j b k c_i=\sum_j\sum_k[j∧k=i]a_jb_k ci=jk[jk=i]ajbk

与或卷积非常类似,按后缀和计算即可。


异或卷积

即要求: c i = ∑ j ∑ k [ j ⊕ k = i ] a j b k c_i=\sum_j\sum_k[j⊕k=i]a_jb_k ci=jk[jk=i]ajbk

定义 F W T ( x ) i = ∑ j = 0 2 n − 1 ( − 1 ) ∣ i ∧ j ∣ x j FWT(x)_i=\sum_{j=0}^{2^n-1}(-1)^{|i∧j|}x_j FWT(x)i=j=02n1(1)ijxj

若a和吧异或卷积后的结果为c,则 F W T ( c ) i = F W T ( a ) i ⋅ F W T ( b ) i FWT(c)_i=FWT(a)_i·FWT(b)_i FWT(c)i=FWT(a)iFWT(b)i

证明:
F W T ( c ) i = ∑ j = 0 2 n − 1 ( − 1 ) ∣ i ∧ j ∣ c j FWT(c)_i=\sum_{j=0}^{2^n-1}(-1)^{|i∧j|}c_j FWT(c)i=j=02n1(1)ijcj

                  = ∑ j = 0 2 n − 1 ( − 1 ) ∣ i ∧ j ∣ ∑ k = 0 2 n − 1 ∑ l = 0 2 n − 1 [ k ⊕ l = j ] a k b l \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\sum_{j=0}^{2^n-1}(-1)^{|i∧j|}\sum_{k=0}^{2^n-1}\sum_{l=0}^{2^n-1}[k⊕l=j]a_kb_l                  =j=02n1(1)ijk=02n1l=02n1[kl=j]akbl

                  = ∑ k = 0 2 n − 1 ∑ l = 0 2 n − 1 ( − 1 ) ∣ ( k ⊕ l ) ∧ i ∣ a k b l \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\sum_{k=0}^{2^n-1}\sum_{l=0}^{2^n-1}(-1)^{|(k⊕l)∧i|}a_kb_l                  =k=02n1l=02n1(1)(kl)iakbl

                  = ∑ k = 0 2 n − 1 ∑ l = 0 2 n − 1 ( − 1 ) ∣ ( k ∧ i ∣ a k ⋅ ( − 1 ) ∣ ( l ∧ i ∣ b l \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\sum_{k=0}^{2^n-1}\sum_{l=0}^{2^n-1}(-1)^{|(k∧i|}a_k·(-1)^{|(l∧i|}b_l                  =k=02n1l=02n1(1)(kiak(1)(libl

                  = ( ∑ k = 0 2 n − 1 ( − 1 ) ∣ k ∧ i ∣ a k ) ( ∑ l = 0 2 n − 1 ( − 1 ) ∣ l ∧ i ∣ l b l ) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =(\sum_{k=0}^{2^n-1}(-1)^{|k∧i|a_k})(\sum_{l=0}^{2^n-1}(-1)^{|l∧i|lb_l})                  =(k=02n1(1)kiak)(l=02n1(1)lilbl)

                  = F W T ( a ) i ⋅ F W T ( b ) i \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =FWT(a)_i·FWT(b)_i                  =FWT(a)iFWT(b)i

所以 c c c 即为对 a , b a,b a,b 分别求出 FWT 后对应相乘再做 FWT 的逆变换即可。

我们分别对每个位进行考虑。
对于第 i i i 位和第一个不包含 i i i 的集合 S S S,设 x = a S , y = a S + a i x=a_S,y=a_{S+a^i} x=aS,y=aS+ai,则有新的 a S = x + y , a S + 2 i = x − y a_S=x+y,a_{S+2^i}=x-y aS=x+y,aS+2i=xy。具体代码如下:

for(int i=1;i<(1<<n);i<<=1){
	for(int j=0;j<(1<<n);j+=(i<<1)){
		for(int k=j;k<j+i;k++){
			int x=a[k],y=a[k+i];
			a[k]=x+y,a[k+i]=x-y;
		}
	}
}

复杂度为 O ( 2 n n ) O(2^nn) O(2nn)


子集卷积

即要求: c i = ∑ j ∑ k [ j ∧ k = ∅ , j ∨ k = i ] a j b k c_i=\sum_j\sum_k[j∧k=∅,j∨k=i]a_jb_k ci=jk[jk=,jk=i]ajbk

显然不能直接做或卷积。
考虑到 [ j ∧ k = ∅ , j ∨ k = i ] [j∧k=∅,j∨k=i] [jk=,jk=i] 的条件等价于 [ ∣ j ∣ + ∣ k ∣ = i , j ∨ k = i ] [|j|+|k|=i,j∨k=i] [j+k=i,jk=i],所以可以先将集合按元素个数分类,然后统计答案。

然鹅我们发现对应每一组都操作了 n n n 次 FWT,重复了。可以预处理出所有组的 FWT,对应每队直接对应位相乘累计答案。最后用 FWT 的逆运算返回即可。

复杂度为 O ( 2 n n 2 ) O(2^nn^2) O(2nn2)


子集卷积 exp

即要求: c i = ∑ i 1 , i 2 , . . . i k [ ∣ i 1 ∣ + ∣ i 2 ∣ + . . . + ∣ i k ∣ = ∣ i ∣ , i 1 ∨ i 2 ∨ . . . ∨ i k = i ] a i 1 a i 2 . . . a i k c_i=\sum_{i_1,i_2,...i_k}[|i_1|+|i_2|+...+|i_k|=|i|,i_1∨i_2∨...∨i_k=i]a_{i_1}a_{i_2}...a_{i_k} ci=i1,i2,...ik[i1+i2+...+ik=i,i1i2...ik=i]ai1ai2...aik

考虑按最高位分组,每一组中最多选择一个,所以答案即为所有组子集卷积后的答案。
复杂度为 ∑ i = 1 n O ( 2 i i 2 ) = O ( 2 n n 2 ) \sum_{i=1}^nO(2^ii^2)=O(2^nn^2) i=1nO(2ii2)=O(2nn2)


多项式复合集合幂级数

即要求: c i = ∑ i = 0 n f i a i c_i=\sum_{i=0}^nf_ia^i ci=i=0nfiai,其中 a i a_i ai 为子集卷积。

在上一题的基础上记录当前还有几个要选。
G i , j G_{i,j} Gi,j 表示合并完前 i i i 组后还需要再添加 j j j 个的方案数。初始即为 G 0 , i = F i G_{0,i}=F_i G0,i=Fi,每次添加一组即为 G i , j = G i − 1 , j + G i − 1 , j − 1 F i G_{i,j}=G_{i-1,j}+G_{i-1,j-1}F_i Gi,j=Gi1,j+Gi1,j1Fi,其中 F i F_i Fi 表示第 i i i 组形成的集合。
复杂度为 ∑ i = 1 n O ( 2 i i 2 ( n − i ) ) = O ( 2 n n 2 ) \sum_{i=1}^nO(2^ii^2(n-i))=O(2^nn^2) i=1nO(2ii2(ni))=O(2nn2)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值