组合数学(容斥与反演)
前言
校测被数学干碎了,赶紧来补一点容斥和反演的东西,能补多少算多少吧。
特别说明:这一篇学习笔记是组合数学的第二篇。
容斥
让我们从梦开始的地方讲起。
容斥原理
设全集 \(U\) 中的元素可能拥有 \(n\) 种不同的属性,拥有第 \(i\) 种属性的元素组成集合 \(S_i\)。则有:
这个东西就是小学奥数的容斥原理。证明考虑一个元素的系数应该为 \(1\),有:
但是这种最原始的原理不常用,更多的是考察选手容斥的思想。
例题
在集合 \(S = {1, 2, · · · , n}\) 中,选出 \(m\) 个无序的互不相同的非空子集,使得每个元素的出现次数均为偶数。求选择方案数对 \(10^8+7\) 取模。
数据范围:\(n,m\le10^6\)。
首先这道题的限制很多,我们可以先把它们全部列出来:
- 无序
- 互不相同
- 非空子集
- 每个元素出现次数均为偶数
对于第一个限制我们只需要在最后去标号即可,现在考虑剩下三种如何处理。
在笔者看来,我们做题时可以先去处理相对难处理的限制,然后再减去容易处理的东西。对于这道题而言,限制四有些神秘,我们就先考虑这个东西。假设现在我们设 \(f_i\) 表示选出 \(i\) 个子集满足限制,方案数是什么呢?
其实对于前 \(i-1\) 个子集我们可以任意选,然后在最后一个子集调奇偶性,所以方案数为:\((2^n-1)^{\underline{i-1}}\)。然后我们再加上剩下的限制,这就是用容斥的思想减去不合法的。
对于子集为空的情况,说明前 \(i-1\) 已经合法,所以减去 \(f_{i-1}\);对于有相同的子集,说明剩下 \(i-2\) 个子集已经满足限制,所以减去 \(f_{i-2}\times(i-1)\times(2^n-1-i+2)\)。
所以直接递推就好了,时间复杂度 \(O(n+m)\)。
有 \(n\) 个人,\(m\) 门课,每位同学在第 \(i\) 门课上的分数是 \([1, U_i ]\) 之间的一个整数。已知小 \(B\) 每门课的排名,第 \(i\) 门课的排名为 \(R_i\)。其中排名的定义为有且仅有 \(R_i − 1\) 位同学这门课的分数大于小 \(B\) 的分数,有且仅有 \(n − R_i\) 位同学这门课的分数小于等于小 \(B\)(不包括他自己)。此外,还知道恰好有 \(k\) 位同学每门课成绩都小于等于小 \(B\) 的成绩(称这 \(k\) 同学被小 \(B\) 碾压),求合法的得分情况的方案数对 \(10^9+7\) 取模。
数据范围:\(n,m\le100,U_i\le10^9\)。
这道题可以分为三部分,首先选出 \(k\) 个同学被碾压,然后钦定分数相对大小,最后确定分数的方案。这些直接乘法原理乘起来即可。
第一部分是 \({n-1\choose k}\) 没啥好说的。
第二部分,考虑每一门学科分数比 \(B\) 更高的会分配给没有被碾压的,但是这样会存在有人没有分到的情况,于是再给一个容斥系数,就有:
第三部分,枚举每一科以及成绩,有:
把最后一个 \(\sum\) 看成关于 \(j\) 的 \(n-k\) 次多项式然后拉插使劲插一下即可,时间复杂度 \(O(n^2m)\)。(当然你写 \(O(n^3m)\) 也不是不行)
min/max 容斥
一个一点也不平平无奇的式子:
其中 \(\max(S)\) 表示集合中元素最大值, \(\min(S)\) 同理。
证明:
我们考虑集合中第 \(k+1\) 大的元素的系数,有:
第二个同理。
或许你会觉得这个式子很奇葩,我既然能求最小值为什么不能求最大值呢?您别说有的时候还真是!这种东西在期望中最常见,并且因为期望有线性性所以可以直接用 \(E\) 套 \(\min/\max\) 容斥。
于是就有:
证明:
我们直接把期望拆开做,就有:
然后我们使用之前证明的容斥:
拓展-kth Min/Max
证明:
与之前的类似,还是考虑集合中第 \(i+1\) 大的元素。但是现在要求 \(kth\) 所依集合大小至少为 \(k\),于是就有:
然后再套上期望就无敌了。
例题
按位或 (本题要用到一点卷积知识,建议提前学习后完成此题)
你需要将数字 \(0\) 变成 \(2^n-1\),现在有 \([0,2^n-1]\) 这些数字。每秒你会随机在区间中选择一个数按位或上当前数,问期望时间。
数据范围:\(n\le 20\)。
考虑构造一个函数 \(t_i\) 表示元素 \(i\) 变成一的期望时间,我们就可把期望套上一个最大值。
我们设 \(E(\max(S))\) 表示一个集合中所有元素都变成一的期望时间(我们把每个数看成一个集合,其二进制下每一位都是集合里的元素),对于 \(E(\min(S))\) 我们可以类似地定义。
然后问题的答案就是 \(E(\max(S))\),其中 \(S\) 是 \(2^n-1\) 所代表的集合。因为期望具有线性性,所以我们直接给它套上 \(\text {min/max}\) 容斥,就有:
然后问题就转化成求 \(E(\min(T))\) 了。
现在我们暴力拆开上面的东西,就有:
其中后面表示第一次出现一的时间为 \(i\) 的概率。第一次出现一的时间为 \(i\),说明前面都没有出现过,所以有:
(其中 \(P(K)\) 表示选中 \(K\) 的概率)
可以注意到这些 \(P(\min(T)==i)\) 拆开后的和是一个等比数列,所以答案就可以写成:
现在的问题就在于如何快速求解 \(\sum_\limits{K\cap T=\varnothing}P(K)\)。我们把它写成 \(\sum_\limits{K\subseteq \complement_TS}P(K)\) 这种形式就可以用 \(\text{FMT}\) 卷了,时间复杂度 \(O(n2^n)\)。
有 \(n\) 种物品, 每一秒会随机获得某种某一种物品,第 \(i\) 种物品出现的概率为 \(p_i\over m\),其中 \(m = \sum p_i\),求收集到至少 \(x\) 种不同物品的期望时间对 \(998244353\) 取模。
数据范围:\(n\le1000,m\le10^4,|n-x|\le10\)。
我们可以类比上一道题,将期望套上最大值。然后注意到 \(|n-x|\le10\),于是令 \(k=n-x+1\),题目就转化成求解 \(E(\max(S))\) 的形式了。然后套路地容斥一下我们就需要求解所有 \(E(\min(S))\)。
对于一个 \(E(\min(S))\) 容易知道有:
但是我们直接枚举肯定爆炸了。所以我们需要合并一些项,让枚举一个东西的复杂度能够被接受!
现在的式子是这样的:
其中 \(k\)、\(m\) 是常数,如果我们枚举 \(|T|\) 和 \(\sum p_i\) 时间是 \(O(nm)\) ,这是可行的。所以我们就尝试用 dp 求出每种情况下的系数。设 \(f_{i,j}\) 表示考虑前 \(i\) 个元素,\(\sum p=j\) 的容斥系数。转移时讨论第 \(i\) 个元素选或不选,如果选就直接转,否则就要加上一个容斥系数:
用 \(f\) 代替,并且增加一维就变成了:
时间复杂度 \(O(nmk)\),注意要滚第一维。
在一棵有 \(n\) 个点的树上随机游走,并且能重复走某条边。求走完所有给定点的期望步数。固定起点,多测。
数据范围:\(n\le18,q\le5000\)。
还是套路地转化题意,先把答案表示成 \(E(\max(S))\) 第形式,然后容斥后就是求 \(E(\min(S))\) 的值。对于这道题是求走到集合 \(S\) 中任一点的期望步数。显然是树上的期望 dp,然后考虑倒推,设 \(f_i\) 表示从 \(i\) 开始期望走多少步第一次到 \(S\) 中任一点。状态也是容易写的:
如果你草率地硬套高消就 T 飞了,所以考虑树有什么特殊的性质/结构。
不难发现这个式子可以用待定系数法从叶子节点递推回根,然后考虑把转移式里的 \(f\) 稍微分一下类:
我们考虑把 \(f_i\) 写成 \(k_if_{fa_i}+b_i\) 的形式,于是有:
我们求出所有 \(f_i\) 的递推式后就可以线性时间求所有 \(f\),比高消优秀得多!最后再来思考如何统计答案。
考虑答案写成如下形式:
如果直接枚举子集还是 T 飞,但是对于不同的询问 \(S\) 我们似乎不会影响到对于 \(T\) 的答案,于是高位前缀和预处理一下询问时就可以 \(O(1)\) 查了。
反演
这是一个听着很高大上,实际不简单(因为wtcl)的东西。
反演的实质
对于形如下面的式子,我们称左右两式互为反演式:
然后 \(f\) 和 \(g\) 可以看成只有一行的矩阵(也就是向量),这个式子就可以看成矩阵乘法求逆(解向量)。
我们可以把反演看成以下形式:
其中反演系数 \(A\)、\(B\) 均为 \(n\) 阶矩阵,基于此有:
- \(AB=I\),将 \(A\overline{X}\) 代入 \(\overline{Y}\) 可得;
- 将 \(A^T\) 代入 \(A\)、\(B^T\) 代入 \(B\) 上式仍成立,很显然故不证明。
所以每种反演其实都有两套公式,具体的内容请看后文。
子集反演
首先我们需要知道子集反演解决什么样的问题:在恰好是某个集合与至少/至多是此集合之间转换。
如果我们求一个特定的符合要求的集合 \(A\),设 \(f(S)\) 表示 \(A=S\) 的答案,\(g(S)\) 表示 \(S\subseteq A\) 的答案,我们钦定选择了 \(T\subseteq S\),就有 \(g(S)=\sum_{T\subseteq S}f(T)\),反演得到:\(f(S)=\sum_{T\subseteq S}(-1)^{|S|-|T|}g(T)\)。
证明:
例题
给一张 \(n\) 个点的简单无向图,再给一棵 \(n\) 个点的树,现在要给这棵树重标号,问有多少种重标号的方案使得这棵树是原图的一棵生成树。
数据范围:\(n\le17,m\le{n(n-1)\over2}\)。
首先你会看到 \(n\) 很小,然后你会想到 \(2^{17}\) 大概是 \(10^5\)(略大),所以我们可以去思考一个状压 dp。设 \(f_{u,i,S}\) 表示树上 \(u\) 对应图上 \(i\) 且 \(u\) 的子树对应到集合 \(S\) 的方案数。转移是 \(f_{u,i,S}\leftarrow f_{v,j,T},v\in son_u,(i,j)\in E,T\subset S\),但是 \(O(3^nn^3)\),因为要 \(O(3^n)\) 枚举子集还有枚举对应点的 \(O(n^3)\)。然后你灵光一现,这不 FWT 优化吗?于是做到 \(O(2^nn^4)\) 还是炸。
该如何破局呢?
考虑到算法的瓶颈在于枚举子集,在枚举时有要求:任意两点对应的点不能相同。我们先不考虑这个限制。怎么个不考虑呢?我们引入一个 \(g(S)\) 表示将树上的点对应到 \(S\) 的子集中的方案数,若 \(F(S)\) 表示对应到 \(S\) 的方案数,稍微容斥就有:
这不就对应了标题的子集反演吗?于是就可以得到:
然后我们就可以先去求解 \(g(S)\),重新设 \(dp_{u,i,S}\) 表示树上 \(u\) 对应图上 \(i\) 且点在 \(S\) 的方案数,就有转移:
实际写的时候把最后一维扔掉,最后把 \(dp_{root,i,S}\) 拿去熔了就对了。
总结
感觉这类题比较容易识别,因为题目中 \(n\) 的范围很小,可以考虑枚举状态/集合,然后对于不好求的我们可以先放宽限制,然后尝试用一些方法去增加限制或者去找之间的联系,比如容斥改写状态/条件。但最终一道题还是要以寻找关键性质为主,所以我们应当在刷题中反复锻炼思维。
二项式反演
二项式反演是最常见的反演之一,下面给出两种形式并证明第一种。
形式一:
形式二:
形式一证明:
形式二类似。
常见形式
对于求恰好若干个元素满足条件的题目,若不能直接求,可以考虑先转化成钦定有若干个元素满足条件再套上二项式反演。或者说题目条件太苛刻或难以高效处理,这时若去掉部分限制则有优秀做法,即可考虑容斥/反演。但是在使用前需要寻找足够题目性质,不然可能不能进行优化或转换。
二项式反演只是我们处理刁钻限制条件的手段,但真正的思考需要到位才行。一个题可以尝试的方法有很多,但是我们在做题时不能盲目 bfs,而是需要结合题目具体条件(特殊性质、已知、问题)筛选合适的做法。
例题
一个有 \(N\) 个元素的集合有 \(2N\) 个不同子集(包含空集),现在要在这 \(2N\) 个集合中取出若干集合(至少一个),使得它们的交集的元素个数为 \(K\),求取法的方案数,答案模 \(10^9+7\)。
数据范围:\(1\le K\le N\le10^6\)。
我们设 \(f(i)\) 表示选出子集大小恰好为 \(i\) 的方案数,然而我们发现这个东西不好转移。但是,如果我们先求出一个限制条件少一点但是比较好求的东西 \(g(i)\) 再去求 \(f(i)\) 就会简单许多(也许。
于是就有 \(g(i)\) 表示钦定 \(i\) 个元素在交集中(其他元素不考虑),这样 \(g(i)\) 就比较好求了,我们可以把 \(g(i)\) 的式子写出来:\(g(i)={n\choose i}(2^{2^{n-i}}-1)\)。为什么呢?首先我们需要从 \(n\) 个元素中选择 \(i\) 个元素,所以有 \(n\choose i\),然后对于剩下 \(n-i\) 个元素,我们可以列举出可能存在的集合的可能,也就是 \(2^{n-i}\) 种可能,对于这些集合我们可以选可以不选,但是题目要求至少选一个,所以就是一个 \(2^{n-i}\) 元集去掉空集,然后选的元素与不选的元素之间互有影响所以是乘法原理。
然后就是去找 \(f\) 与 \(g\) 的关系了。其实对于 \(g\),我们还有另一种求法:\(g(i)=\sum^n_{j=i}{j\choose i}f(j)\)。其实就是对于选出子集大小恰为 \(j\) 的方案中再去选出 \(i\) 个,与第一种方法等价。
然后看到后面这坨直接二项式反演就可以得到:
然后直接算就行。
有两个序列 \({a_i},{b_i}\) 保证所有元素互不相同。你需要重排 \(b\) 序列,使得恰好有 \(k\) 个 \(i\) 满足 \(a_i>b_i\)。
\(0<k\leq n\leq2000\)
因为每一个 \(a,b\) 关系都是相对独立的,所以可以先对 \(A=\{a_i\}\) 排序。
然后就能想到一个 \(dp_{i,j}\) 表示考虑前 \(i\) 对,恰好有 \(j\) 对满足条件,设 \(f_i\) 表示所有数中恰有 \(i\) 对的方案,所以 \(f_i=(n-i)!dp_{n,i}\),且 \(f_k\) 即为最后答案。然后就做完了!
但是这个东西似乎无法直接转移((,所以我们需要换一下思路,那么不妨放宽条件,我们重新定义一个 \(dp_{i,j}\) 表示钦定 \(j\) 对满足条件,设 \(g_i\) 表示所有数中钦定有 \(i\) 对的方案,然后稍加讨论就能转移了:
其中 \(cnt(a_i)\) 表示 \(B=\{b_i\}\) 中比 \(a_i\) 小的数的个数,这个似乎可以直接维护。
然后我们可以找找 \(f\) 与 \(g\) 的关系(这不就是二项式反演的组合意义吗),然后因为:
根据二项式反演有:
莫比乌斯反演
对于一些函数,我们无法快速求出其值,但可以快速求出其倍数或约数的值,我们就能通过莫比乌斯反演快速求值。
积性函数
定义:若一个数论函数 \(f(n)\) 满足 \(f(pq)=f(p)\times f(q),\gcd(p,q)=1\),则称 \(f(n)\) 是一个积性函数。如果 \(\gcd(p,q)=k,k\in Z\),仍能满足上式则称 \(f(n)\) 为完全积性函数。
性质:若 \(f(n)\) 与 \(g(n)\) 均为积性函数,则下面函数均为积性函数:
- \(h(x)=f(x^p)\)
- \(h(x)=f^p(x)\)
- \(h(x)=f(x)g(x)\)
- \(h(x)=\sum_{d|x}f(d)g(\frac{x}{d})\)
常见积性函数
-
单位函数 \(\epsilon(n)=[n=1]\)
-
常数函数 \(1(n)=1\)
-
幂函数 \(id_k(n)=n^k\),其中 \(id_1(n)\) 简记为 \(id(n)\)
-
因数个数函数 \(d(n)=\sum_{d|n}1\)
-
除数函数 \(\sigma_k(n)=\sum_{d|n}d^k\),其中 \(k=0\) 时就是因数个数函数,\(k=1\) 时为因数和函数,简记为 \(\sigma(n)\)
-
欧拉函数 \(\varphi(n)=\sum^n_{i=1}[\gcd(i,n)=1]\)
-
莫比乌斯函数
\[\mu(n)=\begin{cases}1&n=1\\ 0&n \text{含有平方因子}\\ (-1)^k& k \text{为} n \text{本质不同的质因子个数}\end{cases} \]
狄利克雷卷积
性质
- 交换律:\(f*g=g*f\)
- 结合律:\((f*g)*h=f*(g*h)\)
- 分配律:\((f+g)*h=f*h+g*h\)
- 如果 \(f,g\) 是积性函数,则 \(f*g\) 也是积性函数。
有了这些性质,我们将前面的某些积性函数卷一卷就可以发现一些有趣的事实。
比较重要的卷积
\(id*1=\sigma\)
将 \(id\) 与 \(1\) 卷起来就是求因数和,根据狄利克雷卷积的式子结合函数的意义可以理解。
\(1*1=d\)
与上一个式子相似,不过多赘述。
\(\varphi*1=id\)
证明:
设 \(n=p_1^{c_1}p_2^{c_2}\dots p_k^{c_k}\),因为 \(\varphi\) 是积性函数,则只用证 \(p^c\) 时成立即可。
应用-欧拉反演:\(n=\sum_{d|n}\varphi(d)\)
\(\mu*1=\epsilon\)
证明:当 \(n=1\) 时显然成立,当 \(n>1\) 时,\(n=p_1^{c_1}p_2^{c_2}\dots p_k^{c_k}\)。当我们卷积枚举因数时,对于枚举到的数的质因数 \(\exists c_i>1\),那么这一项对答案没有贡献,于是我们只用考虑 \(\forall c_i=1\) 的情况。
应用-莫比乌斯反演:\([n=1]=\sum_{d|n}\mu(d)\)
莫比乌斯反演的另一种形式(经典形式):\(f*1=g\leftrightarrow g*\mu=f\)
以上就是最基本的卷积,需要无条件记住!接下来我们根据上面的一些东西可以口胡推出另一些式子。
\(f*\epsilon=f\)
\(\varphi*d=\varphi*1*1=id*1=\sigma\)
\(\mu*id=\mu*1*\varphi=\epsilon*\varphi=\varphi\)
\(\mu*\sigma=\mu*1*id=\epsilon*id=id\)
例题
前言:写了这么多前置知识,终于可以开始最有趣的推式子环节了!
注:以下均默认 \(n\le m\)。
其中 \(\mu\) 可以预处理,\(\lfloor\frac{n}{d}\rfloor\) 可以 \(O(\sqrt n)\) 数论分块。
\(\varphi\) 和 \(\mu\) 一样可以预处理,然后就做完了。
令 \(dk=T\),则:
后面那坨可以 \(O(n)\) 预处理。
\(T\) 组询问。一开始给定一个常数 \(K\)。每次询问单独给定 \(n\)。请你求出:
数据范围:\(n\le10^7,T = 10^4\),\(1 \leq K < 2^{31}\)。
话不多说开始推式子:
这里最后两个 \(\sum\) 可以预处理,令 \(sum(n)=\sum\limits_{i\le n}\sum\limits_{j\le n}(i+j)^K\),又有:
令 \(T=td\):
后面的 \(T^K\times\sum\) 是积性函数可以直接筛后记录前缀,然后答案用数论分块 \(O(\sqrt{n})\) 查询。
围护 \(n\) 个初始为空的可重集,支持 \(4\) 种操作:
- 令集合 \(x\) 等于 \(\{v\}\)。
- 令集合 \(x\) 等于集合 \(y\) 与 \(z\) 的并。
- 令集合 \(x\) 等于集合 \(y\) 与 \(z\) 的积,\(A*B=\{\gcd(a,b)|a\in A,b\in B\}\)。
- 询问 \(v\) 在集合 \(x\) 中出现次数模 \(2\) 的结果。
数据范围:\(n\le10^5,q\le10^6,v\le7000\)。
考虑到 \(v\) 的范围很小,且查询的是出现次数模 \(2\) 的结果,所以果断对每一个集合开一个 bitset 记录答案,然后对于1、2操作我们直接维护即可。
因为有 \(ans_{x,i}\equiv\sum\limits_{j}\sum\limits_{k}ans_{y,j}ans_{z,k}[(j,k)==i]\pmod{2}\),这非常的可以反演。所以我们改成记录一个 \(f_{x,i}=\sum\limits_{i|j}ans_{x. j}\),就有:\(ans_{x,i}=\sum\limits_{i|j}f_{x,j}\mu({j\over i})\)。其中 \(\mu({j\over i})\) 可以预处理,\(f\) 需要维护,这就解决了操作 \(4\),还剩操作 \(3\) 了。
如何维护 \(f\) 呢?我们先把式子写出来:
于是就做完了。
nb 题目!
\(T\) 组询问求:
数据范围:\(A,B,C\le 10^5,\sum\le2\times10^5\)。
我们还是考虑反演,上面我们蒸锅 \(1*1=d\),这里直接用,然后你就会得到一坨大的,具体就是你对 \(i,j,k\) 全部反演,然后就会出现 6 个 \(\sum\),整理得到:
其中 \(TA,TB,TC\) 是两两的 \(\text{lcm}\)。然后这道题最妙的点来了!我们如何考虑有贡献的三元组呢?首先我们可以将需要满足的条件列出来:
- \(\mu(i)\neq0,\mu(j)\neq0,\mu(k)\neq0\);
- \(TA,TB,TC\) 均不大于 \(A, B,C\)。
然后我们可以直接忽略 \(\mu(i)=0\) 的数。对于剩下的,考虑第二种限制满足偏序关系,我们可以把每个数看成一个点,对于合法的一对二元组连边,最后再统计三元环即可。我们可以给边定向以优化常数。时间复杂度是 \(O(m\sqrt m)\),\(m\) 为边数。
(莫反先咕了,因为感觉大多都有点板,等找到好题 我一定会回来~的!)
斯特林反演
还没有掌握斯特林数基础知识的读者可参见我的另一篇博客,下面直接给出反演形式。
一般形式
证明(用到反转公式)(两形式类似故只证明第一种):
常见题目形式
没啥好说的,形似二项式反演,神似二项式反演。只不过在做题中要考虑清楚题目组合意义,不要把两种反演混为一谈。
例题
TopCoder13444
给出一个 \(n\times m\) 大小的矩形,每个位置可以填上 \([1, c]\) 中的任意一个整数,要求填好后任意两行互不相同且任意两列互不相同,两行或两列相同当且仅当对应位置完全相同,求方案数对 \(10^9+7\) 取模。
数据范围:\(n,m\le5000\)。
这种就是典型的把难处理的限制先转化成好处理的然后再反演的问题。
我们先只考虑 \(g(m)\) 表示 \(n\) 行 \(m\) 列中保证行不同的方案数,易得 \(g(m)=(c^m)^{\underline n}\)。然后考虑一个 \(f(m)\) 表示 \(n\) 行 \(m\) 列中保证行和列都不同的方案数,再考虑如何用 \(f\) 表示 \(g\)。
不妨换一种思考角度。若两列相同,我们就把它们划分到同一个集合中。所以我们就可以枚举把 \(m\) 列划分到 \(i\) 个非空集合,就有:
反演一下得到:
代入 \(g(m)=(c^m)^{\underline{n}}\) 后即可 \(O(n^2)\) 计算。
定义两个结点数相同的图 \(G_1\) 与图 \(G_2\) 的异或为一个新的图 \(G\),其中如果 \((u, v)\) 在 \(G_1\) 与 \(G_2\) 中的出现之和为 \(1\),那么边 \((u, v)\) 在 \(G\) 中,否则这条边不在 \(G\) 中。现在给定 \(s\) 个结点数相同的图 \(G_{1∼s},S = {G_1,G_2,\dots ,G_s}\),请问 \(S\) 有多少个子集的异或为一个连通图?
数据范围:\(2\le n\le10,1\le s\le60\)。
这道题和连通性相关,于是考虑维护连通块。若我们直接求解有 \(i\) 个连通块的方案数你发现会不太可做,考虑放宽限制。我们设 \(f(i)\) 表示钦定 \(i\) 个点集两两之间不连通的方案数,\(g(i)\) 表示恰有 \(i\) 个连通块的方案数。于是有:
于是就可以斯特林反演得到:
考虑答案为:
所以我们只需要求出所有 \(f\) 即可。
因为 \(f\) 的求解似乎要枚举点集划分,而枚举数量是 \(\sum\limits_{i\le n}{n\brace i}\) 的,这就要我们找到合适的方法计算出方案数。
注意到一条边的组成是:\(\bigoplus\limits_{edge\in G_i}a_i=0\),其中 \(a_i\) 代表选或不选。那么对于一个枚举到的点集划分就有一些异或方程。对于这些方程,我们并不需要知道它们的解,只用求出方程组的秩即可。这个东西用线性基做就行了。时间复杂度 \(O(Bell_n\times s\times n^2)\)。
后记
完稿时间:2025.1.24 19:55
虽说很早就开始写了一点内容,但是这篇博客的主体都是这一天左右的时间写的,写完是如释重负啊!明天打完模拟赛听了评讲就差不多结束年前的课了,但是我感觉还是有很多东西没有写。我数学太弱了,亟待加强!

浙公网安备 33010602011771号