首页 > 其他分享 >浅谈集合幂级数

浅谈集合幂级数

时间:2024-02-18 19:33:58浏览次数:30  
标签:浅谈 limits 卷积 sum times 幂级数 int exp 集合

叠甲:读者很菜。

集合幂级数是一个很厉害的东西。

我们对于是有限集的全集 \(\mathbb{U}={1,2,\dots n}\),我们利用占位符 \(x^S\) 来表示一个序列 \(f\),其中对于 \(S\subseteq \mathbb{U}\) 的值为 \(f_S\)。

一般记为 \(F=\sum\limits_{S\subseteq \mathbb{U}}f_Sx^S\)。

对于占位符的运算,有 \(x^S\times x^T=\begin{cases}x^{S\cup T}&,S\cap T=\varnothing\\0&,S\cap T\neq \varnothing\end{cases}\)。

子集卷积

我们考虑最基本的卷积运算:

已知 \(F=\sum\limits_{S\subseteq \mathbb{U}}f_Sx^S\) 和 \(G=\sum\limits_{S\subseteq \mathbb{U}}g_Sx^S\) 如何求解 \(H=F\times G\)。

【模板】子集卷积

如果运算有 \(x^S\times x^T=x^{S\cup T}\),这就是普通的或卷积,可以 \(O(n2^n)\) 实现。

但是并不是,只有在 \(S\cap T=\varnothing\) 的时候才会做贡献,考虑在或卷积的基础上增加一些修改,使得其满足这个条件。

我们知道 \(|S|+|T|\ge |S\cup T|\),取等的时候当且仅当 \(S\cap T=\varnothing\),这就完美的满足了我们的条件。

所以我们添加一个占位符 \(y\)。\(x^S\) 变成 \(x^Sy^|S|\),则 \((x^Sy^{|S|})\times (x^Ty^{|T|})=x^{S\cup T}y^{|S|+|T|}\),这样就完美的符合了我们的要求。

具体的实现,就是增加以为,这一位的运算是朴素的多项式卷积。

多项式卷积使用暴力算法可以做到 \(O(n^22^n)\),可以用 FFT/NTT 优化到 \(O(n\log n2^n)\),但是常数太大,完全没有必要。

void mul(int *F,int *G,int *H)
{
	memset(f,0,sizeof(f)),memset(g,0,sizeof(g));
	for(int i=0;i<st;i++) f[pct[i]][i]=F[i],g[pct[i]][i]=G[i];
	for(int i=0;i<=n;i++) FMT(f[i]),FMT(g[i]);
	for(int S=0;S<st;S++)
	{
		for(int i=n;~i;i--)
		{
			g[i][S]=1ll*g[i][S]*f[0][S]%Mod;
			for(int j=1;j<=i;j++)
				add(g[i][S],1ll*f[j][S]*g[i-j][S]%Mod);
		}
	}
	for(int i=0;i<=n;i++) iFMT(g[i]);
	for(int i=0;i<st;i++) H[i]=g[pct[i]][i];
}

子集卷积 exp

我们来考虑上面卷积运算的一些组合意义:

如果我们想要查询有 \(f\) 中两个不交集合构成集合对应的方案数,其为 \(\dfrac{F\times F}{2}=\dfrac{F^2}{2}\)。

依此类推选择 \(k\) 个构成的不交集合就是 \(\dfrac{F^k}{k!}\)(除 \(k!\) 的原因是选择这些集合的相对顺序是无关的)。

我们考虑选择若干个不交集合(考虑可以不选),有 \(G=x^\varnothing+\sum\limits_{k=1}\dfrac{F^k}{k!}\)。

发现 \(\sum\limits_{k=1}\dfrac{F^k}{k!}\),这个东西就是 \(\exp F-1\)。也就是说 \(G=\exp F\)。

因此,还是在 \(x\) 维上做或卷积,在 \(y\) 维上我们做多项式 \(exp\),我们就可以通过 \(F\) 来生成 \(G=\exp F\) 了。

\(G=\exp F\),所以 \(G'=(\exp F)'\)。

所以 \(G'=\exp F\times F'\Rightarrow G'=G\times F\)。

\(\sum\limits_{i}ig_iy^{i-1}=(\sum\limits_{i}g_iy^i)\times (\sum\limits_{i}if_iy^{i-1})\)。

所以 \(ng_n=\sum\limits_{i=1}^nf_i\times g_{n-i}\)。这样单次 \(exp\) 可以做到 \(O(n^2)\),所以整体就可以做到 \(O(n^22^n)\)。

而子集卷积 exp 的组合意义就是:选择若干个不交集合组合在一起的所有方案

void exp(int *F,int *G)
{
	memset(f,0,sizeof(f)),memset(g,0,sizeof(g));
	for(int i=1;i<st;i++) f[pct[i]][i]=F[i];
	for(int i=0;i<=n;i++) FMT(f[i]);
	for(int S=0,tmp;S<st;S++)
	{
		g[0][S]=1;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=i;j++)
				add(g[i][S],1ll*j*f[j][S]%Mod*g[i-j][S]%Mod);
			g[i][S]=1ll*g[i][S]*inv[i]%Mod;
		}
	}
	for(int i=0;i<=n;i++) iFMT(g[i]);
	for(int i=0;i<st;i++) G[i]=g[pct[i]][i];
}

子集卷积 ln

有 exp 就自然会有 ln。

既然 exp 是组合,那么 ln 就是拆分。

exp 是已知 \(f\) 得到 \(g\),ln 就是通过 \(g\) 得到 \(f\)。

由于 \(ng_n=\sum\limits_{i=1}^nf_i\times g_{n-i}\),所以 \(ng_n=nf_ng_0+\sum\limits_{i=1}^{n-1}f_i\times g_{n-i}\)(\(g_0=1\))。

\(f_n=g_n-\dfrac{1}{n}\sum\limits_{i=1}^{n-1}f_i\times g_{n-i}\)。

这样实现的复杂度也是 \(O(n^22^n)\) 的。

组合意义就是:拆分成若干个不交集合

void ln(int *F,int *G)
{
	memset(f,0,sizeof(f)),memset(g,0,sizeof(g));
	for(int i=1;i<st;i++) f[pct[i]][i]=F[i];
	f[0][0]=1;
	for(int i=0;i<=n;i++) FMT(f[i]);
	for(int S=0,tmp;S<st;S++)
	{
		for(int i=1;i<=n;i++)
		{
			g[i][S]=f[i][S],tmp=0;
			for(int j=1;j<i;j++)
				add(tmp,1ll*j*g[j][S]%Mod*f[i-j][S]%Mod);
			del(g[i][S],1ll*tmp*inv[i]%Mod);
		}
	}
	for(int i=0;i<=n;i++) iFMT(g[i]);
	for(int i=0;i<st;i++) G[i]=g[pct[i]][i];
}

标签:浅谈,limits,卷积,sum,times,幂级数,int,exp,集合
From: https://www.cnblogs.com/Xun-Xiaoyao/p/18019800

相关文章

  • 浅谈iPaaS对企业转型的重要性
    面对数字化转型的大浪潮,众多企业都期望着能快速实现全面的数字化转型,让企业在日益激烈的竞争中拥有更稳的市场地位,提升自身的实力及能力,奠定更坚实的基底。但在数字化转型过程中,部分企业数字化基础水平较薄弱,集成方面更多的是采用传统的集成方式,集成结构单一、功能间不能复用、往......
  • 7.NET中GRPC进阶,可空类型,返回集合
     1.添加两个类,一个类型可空,一个不可空publicclassPerson1{publicintId{get;set;}publicdoubleMoney{get;set;}publicfloatWeight{get;set;}publicboolGender{get;set;}publiclongPhoneNum{get;set;}publicst......
  • Java集合篇之深入解析LinkedList
    写在开头作为ArrayList的同门师兄弟,LinkedList的师门地位逊色不少,除了在做算法题的时候我们会用到它之外,在实际的开发工作中我们极少使用它,就连它的创造者都说:“Iwroteit,andIneveruseit”,想想颇有点好笑,但这并不影响我们去学习它,个人认为它底层的链表逻辑对于我们代码思想......
  • 集合
    Collection集合特点**1、List系列集合:添加的元素是有序、可重复、有索引。**子类常用到ArrayList、LinkedList:有序、可重复、有索引。arrlist底层原理,默认创建一个长度为10的数组,存满时会创建到1.5倍,再满就按照实际长度二者的区别是数据结构不同linkedlist底层原理基......
  • Java集合篇之深入解析ArrayList,这六问你答的上来吗?
    写在开头开年第一篇,先祝各位新的一年身体健康,学业有成,事业有成哈,春节期间就是咔咔乱吃,咔咔乱玩,把学习都抛一边子去了,已经9天没有学习了,深深的懊悔,从今天开始,2024年的学习正式开启,一起给我猛冲!!!书接上回,我们开启了Java集合部分的学习,今天我们就来看一下List,其中它的核心有两个,一个......
  • 修改被迭代的集合
    在遍历过程中如果尝试修改正在被迭代的集合可能会抛出ConcurrentModificationException异常。因此,对于可变操作建议使用Iterator的remove()方法或者在StreamAPI中新建一个新的映射结构。通义千问挺好用的metricThresholdMap.setL7Threshold(metricThresholdMap.getL7Thr......
  • Python笔记09——Set(集合)
    九、集合9.1基础集合(set)是一个无序的不重复元素序列,可进行交、集、差等常见的集合操作。与序列的区别:无序,每次输出顺序随机;元素不重复;创建格式:parame={value01,value02,...}或者set(value)(创建空集合只能用set())创建集合示例set1={1,2,3,4}#直接使用......
  • Go语言精进之路读书笔记第24条——方法集合决定接口实现
    24.1方法集合方法决定接口实现:如果某个自定义类型T的方法集合是某个接口类型的方法集合的超集,那么就说类型T实现了该接口,并且类型T的变量可以赋值给该接口类型的变量Go语言规范,对于非接口类型的自定义类型T:类型T,方法集合由所有receiver为T类型的方法组成类型*T,方法集合由所......
  • 迎龙年浅谈 Binary Indexed Trees
    什么是BinaryIndexedTrees?就是树状数组啦。树状数组,是一种高级数据结构,用于高效地解决某一类问题。那么这一类问题是什么呢?那么让我们一起来看一下:问题引入给定一个序列\(a\),给定\(Q\)个\(l,r\),求\(\sum_{i=l}^ra_i\)。这一类问题,我们明显可以暴力枚举,时间复杂度为......
  • 集合
    一.集合框架1.单例集合的体系结构  List接口:1.有序的集合。2.允许存储重复的元素。有索引,可以使用普通for循环。ArrayList:底层是数组实现的,查询快增删慢。LinkedList:底层是链表实现的,查询慢增删快。  Set接口:1.不允许存储重复......