集合幂级数学习笔记

推荐学习:陈昕阳同志在APIO2025讲课课件《集合幂级数在子图计数问题上的应用》


认识集合幂级数

集合幂级数是近年来兴起的信息学考点,24年25年中,集合幂级数出现了三次,分别是联合省选2024D2T2重塑时光、联合省选2025D2T2岁月、NOI2025D2T2集合。

笔者以为(其实是瞎猜的),集合幂级数在2014年第一次在我国信息学奥林匹克出现。
吕凯风同志曾在集训队论文中提到集合幂级数。

当我们遇到有关集合的问题时,我们可能需要运用集合幂级数。

集合幂级数的基本操作

泰勒展开式:\(exp(x)=e^x=\sum_{i=0}\frac{x^i}{i!}\)
我们对做集合幂级数\(A\)\(exp\)要保证\(A(空集)=0\)。同理,我们对做集合幂级数\(A\)\(ln\)要保证\(A(空集)=1\)。这个是和我们搞FFT、NTT的多项式一样的。

用以下代码求集合幂级数 \(exp\)\(ln\) 和逆。

void Jhmjss(long long *a,const int zsc,const int syj,const short Q)
{
	for(int w=0;w<zsc;w++) h1[ypx[w]][w]=a[w];
	for(int i=0;i<=syj;i++) FWTxor(h1[i],zsc);
	
	long long *h0;h0=new long long[syj+1];
	for(int w=0;w<zsc;w++)
	{
		for(int i=0;i<=syj;i++) h0[i]=h1[i][w];
		if(Q==1) Jhmexp(h0,syj);
		else if(Q==2) Jhmlnn(h0,syj);
		else if(Q==3) Jhmnii(h0,syj);
		else puts("wrong");
		for(int i=0;i<=syj;i++) h1[i][w]=h0[i];
	}
	
	for(int i=0;i<=syj;i++) FWTxor(h1[i],zsc);
	for(int w=0;w<zsc;w++) a[w]=h1[ypx[w]][w]*Nw2[syj]%mod;
	for(int i=0;i<=syj;i++) for(int w=0;w<zsc;w++) h1[i][w]=0;
	
	return;
}
void FWTxor(long long *a,const int zsc)
{
	for(int mid=1;mid<zsc;mid<<=1)
	{
		for(int j=0;j<zsc;j+=(mid<<1)) for(int k=0;k<mid;k++)
		{
			long long x=a[j+k],y=a[j+k+mid];
			a[j+k]=x+y;if(a[j+k]>=mod) a[j+k]-=mod;
			a[j+k+mid]=x-y;if(a[j+k+mid]<0) a[j+k+mid]+=mod;
		}
	}
	return;
}
 
void Jhmexp(long long *a,const int syj)
{
	long long *b;b=new long long[syj+1];
	for(int i=1;i<=syj;i++) b[i]=0;b[0]=1;
	for(int i=1;i<=syj;i++)
	{
		for(int j=1;j<=i;j++) b[i]=(b[i]+b[i-j]*a[j]%mod*j)%mod;
		b[i]=b[i]*NY[i]%mod;
	}
	for(int i=0;i<=syj;i++) a[i]=b[i];
	return;
}
void Jhmlnn(long long *a,const int syj)
{
	long long *b;b=new long long[syj+1];
	for(int i=0;i<=syj;i++) b[i]=0;
	for(int i=1;i<=syj;i++)
	{
		for(int j=1;j<i;j++)
			b[i]=(b[i]+b[j]*a[i-j]%mod*j)%mod;
		b[i]=(a[i]-b[i]*NY[i])%mod;
		if(b[i]<0) b[i]+=mod;
	}
	for(int i=0;i<=syj;i++) a[i]=b[i];
	return;
}
void Jhmnii(long long *a,const int syj)
{
	long long *b;b=new long long[syj+1];
	for(int i=1;i<=syj;i++) b[i]=0;b[0]=my_pow(a[0],mod-2);
	for(int i=1;i<=syj;i++)
	{
		for(int j=1;j<=i;j++) b[i]=(b[i]+a[j]*b[i-j])%mod;
		b[i]=(-b[i]*b[0])%mod;if(b[i]<0) b[i]+=mod;
	}
	for(int i=0;i<=syj;i++) a[i]=b[i];
	return;
}

其中,\(Nw2_x\)表示\(2^{-x}\)\(NY_i\)表示\(i^{-1}\)

\(exp\)\(B_n=\frac{1}{n}\sum_{i=1}^{n}A_iB_{n-i}i,B_0=1\)

\(ln\)\(B_n=-\frac{1}{n}\sum_{i=1}^{n-1}B_iA_{n-i}i,B_0=0\)

求逆:\(B_n=-\frac{1}{n}\sum_{i=1}^{n}A_iB_{n-i},B_0=\frac{1}{A_0}\)

练习题

FWT和FMT及简单应用
P4717 【模板】快速莫比乌斯 / 沃尔什变换 (FMT / FWT)
P3175 [HAOI2015] 按位或

四个模板题
这些题目的题解讲的比我好
P12230 集合幂级数 exp
P12231 集合幂级数 ln
P12232 集合幂级数求逆
P6097 【模板】子集卷积

简单应用
P11734 集训队互测2015 胡策的统计

集合幂级数在子图计数上的应用

主要根据陈昕阳同志在APIO2025讲课课件《集合幂级数在子图计数问题上的应用》整理

连通性限制

数连通子图

给定n个点m条边的简单无向图G=(V,E),求有多少边集E′满足E′⊆E且(V,E′)是连通图。答案对998244353取模。

数连通二分子图

ARC105F Lights Out on Connected Graph

可以做到 \(n=20\)

练习题

QOJ5411 CTT2020 杏仁
简要题意:对于给定的源点\(s\),汇点\(t\),称一张有向图为杏仁,当且仅当这张有向图的边集可以被划分为若干条从s到t的路径,且这组划分满足所有路径的点集仅在\(s\),\(t\)两点相交(设划分出\(k\)条路径的点集分别为\(S_{1\sim k}\),应满足∀\(i\neq j,S_i\cap S_j = {s,t}\))。给定\(n\)个点\(m\)条边(可能有重边自环)的有向图\(G=(V,E)\)以及固定的源汇点\(s\)\(t\),回答\(q\)次询问:每次询问给出点u,询问G有多少杏仁子图满足其包含边\(s→u\),答案对998244353取模。对于\(G=(V,E)\),称\(G′=(V′,E′)\)\(G\)的杏仁子图,当且仅当\(G′\)是杏仁,且V′⊆V,E′⊆E\(,\)V′$内无孤立点。数据规模:\(2≤n≤22,0≤q≤n\)

强连通性、可达性、无环限制

数DAG定向

CF1193A

技巧:DAG容斥

数强连通子图

P11714 [清华集训 2014] 主旋律

笔者认为,数强连通子图非常重要,最好对所写的代码标准化处理。

for(int w=1;w<(1<<n);w++)
{
	int jie=0;
	while(!(w&(1<<jie))) jie++;
	
	for(int x=(w-1)&w;x;x=(x-1)&w)
	{
		if(x&(1<<jie)) c2[w]=(c2[w]-c3[w^x]*c1[x])%mod;
	}
	if(c2[w]<0) c2[w]+=mod;
	
	c1[w]=w2[b4[w]]-c2[w];
	for(int x=(w-1)&w;x;x=(x-1)&w)
	{
		c1[w]=(c1[w]-w2[b4[w^x]]*w2[b3[p0[w]+p0[x]]]%mod*c3[x])%mod;
	}
	if(c1[w]<0) c1[w]+=mod;
	
	c3[w]=c1[w]+c2[w];
	if(c3[w]>=mod) c3[w]-=mod;
}

其中,\(b1_{w,i}\)表示从点集\(w\)连向点\(i\)的有向边数量,\(b2_{i,w}\)表示从点\(i\)连向点集\(w\)的有向边数量,\(b4_{w}\)表示起点和终点都在点集\(w\)的有向边数量。
放进数组\(b3\)的是一个三进制数,记\(w\)为三进制下为\(1\)的位集合,\(x\)为三进制下为\(2\)的位集合,显然这里\(w\)\(x\)无交,那么\(b3\)的这个位置表示起点在点集\(w\)且终点在点集\(x\)的有向边数量。
\(c1_w\)即为点集\(w\)的强连通数量,\(c2\)\(c3\)是辅助数组。

练习题

联合省选2024D2T2重塑时光

联合省选2025D2T2岁月
(笔者只会性质)

双连通性限制

点双连通-连通变换

点双连通生成子图计数

马耀华同志的题解在这个题目的讨论里。
讲得很好,很好理解。

边双连通-连通变换

边双连通生成子图计数

陈昕阳同志有讲,马耀华同志在点双连通生成子图计数的题解中也有提到。
暂时还没有完全理解。

数仙人掌

数仙人掌 加强版

感觉这个放在双连通性限制目录下有点奇怪。

类似于求点双。\(O(2^nn^3)\)

例题:交通管制

UR#30B 交通管制

(笔者不会)

练习题题解

连通性限制:QOJ5411 CTT2020 杏仁

时间复杂度\(O(2^{n-2}n^2+2^{n-2}q)\),空间复杂度\(O(2^{n-2}n+n^2)\)

友情链接

FWT 与集合幂级数 学习笔记 --Ff472130

posted @ 2026-01-12 12:22  carrotcarottes  阅读(53)  评论(1)    收藏  举报