[专题总结]组合计数,容斥(习题篇)
还没写完的 : 组合数乱做,概率期望乱做, 鸽巢,图计数。
一些题目的题解我也写不完了,大概凑合着看,但是把题都放上去了,当个题单应该问题不大吧。
组合数泛做
概率期望泛做
Hdu5036+老博客+省选模拟题
https://www.cnblogs.com/TYubai/p/15473092.html
- 一些问题,只有倒着设计状态才没有后效性,状态通常设计为 \(f_x\) 表示 \(x\) 到终点的答案。
- 求方案数的时候可以考虑统计合法的概率最后乘上总方案数。
AGC034F
这题最简单,最基础的一步就是设计出来 Dp。
\(Dp_{x}\) 代表 \(x\) 变成 \(0\) 的期望次数,容易知道他等于 \(0\) 到 \(x\) 的期望次数。
然后就可以列出方程 \(Dp_{x} = 1+\sum_{j \oplus k = i} Dp_{j}*p_k\)
NOI模拟11.5 C
重要的套路之:求总方案数,在每种方案等概率的时候,转化成期望乘总方案数 (不等概率可以拆成权重份之后等概率)。
这个套路有什么作用呢? 为什么求期望会比求方案简单呢?
一个浅显的作用是每当你发现你计算的每个东西都要都后面乘一个常数,就可以考虑这个套路。
当然,题不会去枚举到它也是没有问题的
设 \(f_x\) 代表 \(x\) 子树内产生逆序对的期望,那么发现困难点在子树如何合并起来。
题解设计了这么一个 DP, \(DP_{x,y}\) 代表把 \(x,y\) 这两个子树合并起来产生的逆序对期望。
其实这个状态定义出来的时候,这道题就被解决了,因为转移是显然的。
不难发现,如果两个点没有祖先关系,那么他们的子树合并顺序是互不影响的。
所以合并两个子树,我们只需要枚举谁在前面,即可对应转移。
两个人合成的拓扑序,第一个一定是 \(x\) 或者是 \(y\), \(x\) 是第一个的概率是 \(\displaystyle\frac{\binom{siz_x+siz_y-1}{siz_x-1}}{\binom{siz_x+siz_y}{siz_x}}=\frac{siz_x}{siz_x+siz_y}\) , 那么,确定了第一位是 \(x\) 之后,我们就可以利用独立的性质,分别计算 \(x\) 和 \(y\) 子树的贡献与 \(x\) 的子树与 \(y\) 子树的贡献, \(\displaystyle g_{x,y}\) 即代表 \(y\) 子树内比 \(x\) 小的数的个数。
所以,本题想到用 DP 求子树间的贡献是关键,启示我们不要害怕设计 DP,有需要的就可以尝试 DP 去解决。
普通容斥泛做
省选模拟12C
题意: 统计有多少个长度为 \(L\) 的序列,满足 \(L\) 的元素全部由 \(S\) 集合构成,且 \(L\) 的任意一个前缀的异或和不属于 \(T\) 集合, 对 \(998244353\) 取模, 数据范围 \(L \leq 4e3, |S|\leq 35, |T| \leq 20\)
暴力可以考虑 \(dp_{i,j}\) 代表确定了前 \(i\) 个数, 异或和是 \(j\) 的方案数。
并没有什么优化的空间, 这种有限制的计数的可以考虑去容斥限制,尤其是这道题,一共 \(n\) 个限制,容斥都已经写道脸上了, 一般比较复杂的计数题都需要考虑容斥。
我们现在需要统计至少有 \(i\) 个地方不合法的方案数,我们先尝试去设计一个暴力的统计方案的 Dp。
\(dp_{i,j,k}\) 代表当前有 \(i\) 个不合法的地方,最后一个不合法的地方在 \(j\) , 序列的前 \(j\) 项异或和是 \(T_k\) 的方案数。
其中 \(G_{i,j,k}\) 代表 \(i\) 个 \(S\) 集合中的数,异或出来 \(T{j} \oplus T{k}\) 的方案数。
答案就是 \(\sum_{i=0}^L(-1)^i*\sum_{j=1}^{L}\sum_{k=1}^{m} dp_{i,j,k}*n^{L-j}\)
乘上 \(n^{L-j}\) 是因为后面的我们没有钦定,可以随便选。
一定不要忘记容斥原理的核心:钦定一些不合法,其余先不选择,最后让不选择的随意选。
这个复杂度其实还是可以优化的,因为我们记录了一个没有太大用处的东西:选了几个,记录他的目的只有到最后统计的时候乘上对应的系数。
划分状态只是因为统计时这一维不同有不同的系数,尝试不划分这个状态而是把这个系数划分到各个阶段,在转移的时候乘上对应阶段的系数,最后为划分的状态就是对应划分状态的数量和系数之积的和。
考虑一共选了 \(i\) 个地方,就会乘上 \(i\) 个 \(-1\) , 那么我们每次选择一个数的时候就乘上一个 \(-1\) ,设计状态 \(f_{j,k}\) 代表最后一个不合法的地方在 \(j\) , 序列的前 \(j\) 项异或和是 \(T_k\) 的方案数。
转移和之前一样,不过是多乘一个 \(-1\) 的系数。
答案就是 \(\sum_{j=1}^{L}\sum_{k=1}^{m} dp_{j,k}*n^{L-j}\)。
容斥这部分复杂度是 \(L^2 |T|^2\) 的,可以通过多项式手段优化,不予讨论, 快速的去求 \(G_{i,j,k}\) ,复杂度 \(m^2n^{n/2}\)。
省选模拟17 C
题意:给定 \(N\) 个球, \(m\) 个盒子,第 \(i\) 个盒子最多放 \(a_i\) 个球,有 \(p_i\) 的概率被你发现。
对于每种分配球的方式,如果不超过盒子最多放球的限制,就称它是一种合法的放球方案。
你如果可以发现至少 \(n\) 个球,那么就称你成功了。
求所有合法的放球方案中你成功的概率之和。
\(m \leq 100, a_i, N \leq 1e9, d |(a_i + 1), N \leq 100d, d\) 是一个常数
这题是多个套路的揉和应用,题意很复杂,我们先来设计一个简单的 \(dp\) 。
\(dp_{i,j,k}\) 代表前 \(i\) 个盒子,一共放了 \(j\) 个球,你发现了 \(k\) 个球的概率之和。
在当前点枚举放了多少个球,发没发现去转移,复杂度 \(O(mN^2)\)
没什么优化前景,这题主要难在每种方案的权值和方案本身有关。
对于这种比较复杂度的题,可以考虑最暴力的想法,并且多考虑几个暴力的方向。
最明显的暴力是枚举放球,再枚举开那些箱子,不妨反过来试试。
我们先枚举开了那些箱子,那么这种情况就有一个对应的概率 (选的 \(p\) 和不选的 \(1-p\) 之积) ,我们只需要统计出来在这种开箱情况下的合法并且开的箱子内至少有 \(n\) 个球的方案数就可以了。
\(Dp\) 并不能使用 \(a_i + 1\) 和 \(d\) 的关系,考虑容斥。
先思考如何容斥求最简单的东西: \(N\) 个球放到 \(m\) 个集合内,不超过球的限制,求方案数。
枚举一个超过限制的集合即可。
\(f(S)\) 代表 \(S\) 集合的 \(a_i+1\) 之和,这是很基础的容斥,钦定不合法,剩下的插版分配。
注意到题目的性质,一个集合的性质只有集合大小和 \(f(S)\) ,注意到 \(d|(a_i+1)\) ,并且 \(N\leq 100d\) ,所以可以对于每个 \(f(S)\) ,dp出其 \(-1\) 系数的和,然后乘上对应的组合数,复杂度是 \(O(m\frac{N}{d})\)
这是一个经典套路,对于一种容斥统计答案的方式计算容斥系数再统一贡献,这是状压枚举集合复杂度不允许并且集合的性质和统计方式之间不独立的一种解决办法(不独立,比如本题, \(f(S)\) 在组合数上,没法 dp 的时候维护并且转移)
假设所有开的箱子在序列的前 \(n_1\) 个,我们现在需要让 \(N\) 个球放到 \(m\) 个盒子内,并且前 \(t\) 个盒子至多能有 \(n_1\) 个球,显然要去容斥个数,所以必须满足前 \(t\) 个盒子至多能有 \(n_1\) 个球, 可以枚举前 \(t\) 个集合放了多少球,然后对两个集合分别容斥.
和原来的思路一样,考虑求出来 \(f(S_1)=x,f(S_2)=y,|T|=sz\) 的容斥系数之和。
设计 \(dp\), \(f_{i,x,y,t}\) 代表前 \(i\) 个盒子,选的盒子内不合法的数量是 \(x\) , 没选的盒子内不合法数量是 \(y\) , 选了 \(t\) 个盒子的容斥后的概率之和。
转移枚举当前点选不选,钦不钦定就可以统计。
但是发现我们还是需要枚举一个 \(x\) ,复杂度过高。
发现我们的初心是要保证前 \(sz\) 个集合内有至少 \(n\) 个球,现在已经有 \(x*d\) 个了。
也就是,问题变成了 前 \(sz\) 个集合放 \(n-x*d\) 个球,一共 \(m\) 个集合放 \(N-(x+y)*d\) 个球的方案数。
我有一个错误的想法,就是先分配 \(n-x*d\) 个球到前 \(sz\) 个集合,在分配剩下的到全部,本质错在区分了两类球,导致重复计算。
正确的做法是枚举第 \(n-x*d\) 个球所在的位置,然后插板计算,这是组合计数的套路了,枚举一个分界点。
NOI模拟7.22 B
先考虑暴力容斥怎么做, 钦定之后直接变成小于等于插板,根据套路就开一个垃圾桶和垃圾球就行。
现在我们枚举一手 \(|S|\) , 另 \(A=n - 1 + m + (c-1)|S|\), 那么只要我们保证 \(A \geq \sum_{i\in S}b^i\) ,我们就可以把它统计入贡献,而统计组合数的经典操作就是展乘下降幂得到 \(x^k\) 的系数然后去 dp \(x^k\) 的和。
把 \(A\) 表示成 \(b\) 进制, 设计一个暴力 dp , \(dp_{i,j,k}\) 代表考虑前 \(i\) 个数,选择了 \(j\) 个 \(b^t\), \(k\) 次方的和是多少。
转移是类似 \(\sum x^k \rightarrow \sum (x+t)^k\) 的形式,直接二项式定理展开暴力转移。
现在再考虑 \(A> \sum b^i\) 的问题,我们枚举一个 \(\sum b_i\) 与 \(A\) 的 LCP,再强制下一位小于它,后面直接和 dp 去合并即可。
具体的,从高到低枚举 \(A\) 的每一位,若是 \(0\) 直接去下一位,是 \(1\) 讨论选择 \(1\) 继续 \(LCP\) 和 选择 \(0\) 这一位小于它的情况, \(>1\) 这位肯定小于它直接和 dp 合并。
Uoj #390. 【UNR #3】百鸽笼
现在我们假设有 \(n+1\) 个人,那么求的就是每一列最后一个满的概率。
这种概率可以相互影响的问题,考虑容斥使其独立。
假设要计算 \(x\) 的答案,枚举一个集合在 \(x\) 前面,那么现在就可以删去不在这个集合并且不是 \(x\) 的数。
那么,现在我们就是要统计一下序列的个数 : 包含 \(a_x\) 个 \(x\), 少于 \(a_i\) 个 \(i\), 且以 \(i\) 结尾,长度为 \(L\) ,贡献是 \((\frac{1}{|S|+1})^L\) , 可以背包 dp ,每次加入一种数然后多重集排列起来。
然后直接用背包 dp 优化容斥的过程,加入一维代表选择了多少个数,对每个数先考虑加不加入在考虑加入几个,顺便转移容斥系数。
然后再考虑优化上述的过程,对每个做一遍太浪费了,先把全部的做出来然后退背包即可。
群论题目
P4980 【模板】Pólya 定理
枚举每个置换之后就是看在环上一次走 \(k\) 步, 会形成多少个环。
这是一个经典结论, \(\gcd(len, k)\) 个,原因是我们其实想找的就是一个最小的 \(t\) 满足 \(tk\equiv0 (\mod len)\) , 显然这个 \(t=\frac{n}{\gcd(len, k)}\) , 这个 \(t\) 的意思是多少步会回去,那么也就有 \(\frac{n}{t}\) 个环。
Bzoj #1547. 周末晚会
看到旋转之后本质相同,硬套一个 Burnside, 之后就相当于对每一个 \(k\), 有一个长为 \(\gcd(k,n)\) 的环,你要求出染色方案数,不用考虑同构,发现这个东西一定是 \(n\) 的因子,一般直接对每个因子求个答案。
现在是一个长度为 \(len\) 的环,每个位置填 \(0/1\), 最后连续的 \(0\) 不超过 \(k\) 个的方案数。
先考虑是个链怎么做,如果想给 dp 降降复杂度的话要考虑少记点状态,这个时候可以想到容斥 dp, \(dp_i\) 代表前 \(i\) 个点合法的方案数, \(dp_i=dp_{i-1}*2-dp_{i-k-2}\) ,因为不合法的唯一情况是在 \(i-1\) 时他的末尾时 \(1+(k)*0\) , 然后你填了一个 \(0\), 所以要花 \(k+2\) 个来钦定。
然后在考虑合并成环,枚举环上交界的地方有几个 \(0\), 然后再两边分别放个 \(1\), 问题变成了链, \(ans=\sum(i+1)dp_{n-i-2}\) , \(i+1\) 是因为把长度为 \(i\) 的 \(0\) 放到交界点有 \(i+1\) 个起点, \(dp_{n-i-2}\) 是因为还要钦定首尾两个白球。
P4128 [SHOI2006] 有色图
我们可以置换的是点,然而我们要给边染色,这就要找点置换带动边置换的规律。
考虑实行一个置换之后,肯定是缩成了若干个简单置换环,设长度分别是 \(len_1,len_2,...,len_k\) , 先考虑环内的情况,不难发现,只有 \(x-y\) (\(x,y\) 分别是这条线两个端点的标号) 相同的边相互置换,故这里的方案数就是 \(\sum \lfloor \frac{len_i}{2} \rfloor\) 。
再考虑两个置换之间的边,发现一条边移动 \({\rm lcm} (len_1,len_2)\) 之后就会回到原位,这中间他变成的每一条边都不相同,所以一条边能走 \({\rm lcm}(len_1,len_2)\) 步,一共有 \(len_1,len_2\) 个集合,最后就会形成 \((len_1,len_2)\) 个集合, 故这部分贡献是 \(\sum_{i} \sum_{j < i} (len_i, len_j)\)。
然后发现贡献之和这些 \(len\) 有关,也没什么优化的办法,所以就暴力枚举所有的 \(len, \sum len = n\), 这就是 \(n\) 的拆分数, \(P(n)\) 甚至在 \(70\) 都可以接受。
现在就是看,枚举一个划分数之后有多少个排列形成这个划分数的集合,直接的想法是多重集排列,但是排列之后我们发现只要环长相等这两个盒子没有区别,所以还要去掉环长的影响,令 \(c_i\) 代表 \(len_i\) 有多少个, \(\displaystyle ans=\frac{n!}{\prod len_i!} \prod (len_i-1)! \frac{1}{\prod c_i!}=\frac{n!}{\prod ((a_i) \times c_i!)}\)。
然后直接套用 polya 即可。
P4708 画画
首先有阶乘的置换同构,先考虑枚举集合划分, 我们就是给每条边染上 \(0/1\), \(0\) 不选 \(1\) 选, 看有多少种不动染色。
首先先考虑每个循环内部,大小是奇数,那么就有 \(\lfloor \frac{siz}{2} \rfloor\) 个循环分解,每个分解都会给所有点度数+2;偶数,有\(\lfloor \frac{siz}{2} \rfloor\) 个循环分解可以+2的同时,还剩下了一种可以给每个个改变奇偶性的循环分解。
再考虑循环之间,根据上题结论一共有 \((siz_1,siz_2)\) 个集合,每个集合会把所有点的度数都加上 \({\rm lcm}(siz_1,siz_2)\)
现在分奇偶性分类讨论
如果两个都是偶数,那么我们可以随便选,因为偶数内部多出来的一个循环自带调整功能。
如果是一个奇数一个偶数,假设 \(siz_1 \And 1\), 那么选一个会给 \(1\) 的所有点度数加一个偶数,并不影响;会给 \(2\) 的所有点度数加一个奇数,但是由于 \(!(siz_2 \And 1)\) , 它内部可以调整,所以也不影响,可以随便选。
如果两个都是奇数,那么选一个就会改变两边的奇偶性,这成了唯一的问题。
现在问题就是一个完全图(每两个点之间有 \(\geq 1\) 条边),有多少种选边的方案使得每个点度数都是偶数。
这是一个经典的图计数问题,我们只需要留出来一个生成树调整每个点的度数即可,也就是除了 点数-1 条边被固定之外,其他的边任意选择。
所以他的贡献就是 \(\displaystyle \sum_{i=1}^k \lfloor \frac{siz_i-1}{2} \rfloor +\sum_{i<j}(siz_i,siz_j)-(\sum_{i=1}^k [siz_i \And 1]-[\exist i, 1 \leq i \leq k, siz_i \And 1])\) ,再结合上题的整数划分到排列的系数即可。
Bzoj #4673. 置换
这么套路计数题,怎么不会做?????
看到这个奇怪的阶:直接反映出是所有循环分解大小的 \(\rm lcm\), 现在有一个显然的暴力,就是枚举划分然后使用经典的划分转排列系数乘上 \(\rm lcm\) 贡献到答案。
发现这题并没有太大必要枚举划分,因为我们并不关心每个联通快的大小,我们只关心 \(\rm lcm\), 这个时候会想到一个暴力的思路, \(dp_{i,j}\) 代表大小为 \(i\), \(\rm lcm = j\) 的方案数,那么转移直接把大小为 \(k\) 的选几个枚举一下全部加入即可, 第二维本质不同的有 \(886231\) 个,还是复杂度很高。
考虑优化,每个 \(>\sqrt n\) 的因子只会出现一次,我们可以把它从状态移动到值里面来记录, 我们称 \(\leq \sqrt n\) 的数是小质数,其他为大质数, 改变状态为 \(f_{i,j}\) 代表大小为 \(i\), 小质数的 \(\rm lcm\) 是 \(j\) 的方案数。
我们把所有大因子相同的数排到一起处理,假设加入这个因子前的状态是 \(f_{i,j}\), 加入的时候对每个数枚举加入了几个,转移到 \(g_{i,j}\), 那么 \(g_{i,j}-f_{i,j}\) 就是小质数 \(\rm lcm = j\), 并且一定包含这个大质数的方案数,我们直接把它乘上 \(p^2\) 贡献到 \(f_{i,j}\) 即可,最后统计答案就是 \(f_{i,j}\times j^2\) 。
CF1229D. Wojtek and Card Tricks
给定 \(n\) 个长度为 \(k\) 的置换,对于每个区间,求出通过使用零次或多次这些置换可以从初始排列 \((1,2,…,k)\) , 得到的不同排列个数, \(n≤2\times 10^5,k≤5\)
可以先找出所有的排列和所有的置换乘法的结果,现在枚举右端点扫描线。
直接维护原图的一颗最大生成树(边的权值是他的下标),然后再维护一下到达这个点的最小的点,可以直接计算贡献,这个是一个经典的贪心,时刻维护最大权有效信息,类似还有带删线性基。
注意每次只加入一条边,不用重新 kruskal, 直接看这条边能替换掉哪条边即可, 复杂度 \(O(nk!)\)
当然还有一个做法,每次暴力 bfs 扩展,由于拉格朗日定理,子群的大小是原群的约数,所以每次扩展成功大小至少翻倍,复杂度也正确。
ARC062D Painting Graphs with AtCoDeer
发现每个点双内部的边互不影响,所以先对每个点双分别算最后乘起来。
分以下情况考虑:
- 只有一个边,贡献是 \(k\)。
- 只有一个简单环,套用 Burnside ,贡献是 \(\sum_i k^{(len, i)}\)
- 其他情况,可以证明边可以随便换,所以直接插板就行了, \(\binom{E+k-1}{k-1}E!\)
第三种情况怎么证明? 肯定要注意>2度的点,发现可以换到这个点旁边再交换再换回去,具体构造不赘述,因为这个结论比较好猜。
SP422 TRANSP2 - Transposing is Even More Fun
发现就是要把一个序列通过任意交换两项变成另一个序列, 经典结论是 \(ans=n-c\) , \(c\) 是 \(a_i\) 向 \(b_i\) 连边,形成的简单环个数(以下称为循环个数),因为交换两项可以把循环个数加一/减一, 我们要把最后序列变成有 \(n\) 个循环,我们又有每次都加一个循环的方法,所以下届就是 \(n-c\) 。
现在就是看 \(i\) 连向 \((i\%2^n)2^m+ \lfloor\frac{i}{2^n}\rfloor\) , 把数写成二进制就是循环左移 \(m\) 位。
又因为我们有所有的 \(n+m\) 位的二进制数,现在就是,有 \(n+m\) 个位,在循环左移 \(m\) 位若干次的群的意义下,每位染色成 \(0/1\), 有多少种染色方法,先看有多少种置换,也就是有多少种本质不同的循环左移 \(km\) 位, 显然是 \(L=\frac{n+m}{(n+m,m)}=\frac{n+m}{(n,m)}\)
直接套用 Burnside, \(\displaystyle Ans=\frac{1}{L}\sum_{i=1}^{L-1} 2^{(n+m,i*(n,m))}\) , 用数论化简以下就可以快速回答询问,不再赘述。
这道题最精妙的地方就在于写成二进制数这个操作, 以后见到 \(k^n\) 相关运算可以考虑写成 \(k\) 进制找规律。
NOI模拟7.15 C. 八月
主要是简单的记录一下带权的 Burnside,也就是给一个点染上染色 \(k\) 有 \(val_k\) 的权值,一种染色方案的权值是所有点权值的积,然后问同构意义下,所有本质不同的染色方案的权值和。
还是考虑证明的过程,考虑统计 std:pair<染色,置换>
, 但是,每种方案带有这个染色的权值。
第一种方法是枚举所有的置换,统计在这个置换下不改变的着色数的权值和, \(\sum_{f\in G} T(f)\) .
第二种方法是枚举所有的着色,统计使得这个着色不改变的置换数再乘上着色的权值, \(\sum_{c\in \mathcal{C}} val(c) f(c)\) .
根据实际意义,有 \(\sum_{f\in G} T(f)=\sum_{c\in \mathcal{C}} val(c) f(c)\) , 带入 \(g(c)=|G|/f(c)\) ,由于置换群,所以等价的着色权值肯定相等,也就得到了 \(Ans=\frac{1}{|G|}\sum_{f\in G} k(f), k(f)\) 代表在 \(f\) 意义下不动的着色的权值之和。
求这个权值之和可以用类似 polya 的东西,还是先拆成循环,每个循环的贡献由 \(k\) 变成了 \(\sum_{i=1}^k val_k^{siz}\), 也就是总代价由 \(k^{\#(f)} \rightarrow \prod_{j=1}^{\#(f)}(\sum_{i=1}^k val_k^{len_j})\) 即可。
省选模拟2.6 B. 梧桐依旧
这题要统计的就是 std:pair<染色,置换>
的个数,把所有的 \(A\) 看做一种染色,把 \(B,\det(B) \not ={0}\) 看做一种置换。
把 Burnside 逆用,可以得到答案就是 群的大小 (\(\det \not ={0}\) 的矩阵的个数)\(\times\) 在所有 \(B,\det(B) \not ={0}\) 的作用下,本质不同的 \(A\) 的个数。
先看怎么求 \(\det \not ={0}\) 的矩阵,他的要求就是满秩,满秩 \(\Leftrightarrow\) 可逆 \(\Leftrightarrow\) 所有行向量线性无关 \(\Leftrightarrow\) 所有列向量线性无关 \(\Leftrightarrow\) \(\det \not ={0}\) , 第一行有 \(p^n-1\) 种选择,第二行除了不能全是 \(0\), 还不能是第一行的倍数,有 \(p^n-p\) 种,以此类推,答案是 \(\prod_{i=1}^n p^n-p^{i-1}\) 。
再来看本质不同的染色数,可以把所有的 \(B\) 看做一个群(显然符合群的定义),那么把所有的 \(B\) 看做可能的所有初等行变换,那么所有的 \(A\) 被分成了若干个集合,这几个集合之间不能互相到达,划分的依据就是矩阵的 秩。
现在枚举一个秩 \(k\),答案就是所有的秩为 \(k\) 的 \(n\times n\) 矩阵数量除以对秩是 \(k\) 的矩阵的变换数量(也就是 \(k\times k\) 的满秩矩阵数量), \(=\prod_{i=1}^k \frac{p^n-p^i}{p^k-p^i}\) 。
答案就是 \(\displaystyle \prod_{i=1}^n p^n-p^{i-1}(\sum_{k=1}^n1+\prod_{i=1}^k \frac{p^n-p^i}{p^k-p^i})\) , 加一是因为还有全 \(0\) 的矩阵。
P4916 [MtOI2018]魔力环
前面的操作都跟周末晚会一毛一样,现在就是我们枚举了一个交界点的数量之 \(i, i\leq k\) 后。
现在就是求 把 \(n-m\) 个白球和 \(m\) 个黑球放到一起, 不能有连续 \(k\) 个黑色的球的方案数。
直接考虑容斥,\(\displaystyle ans=\sum_i^{\min(n-m+1,\frac{m}{k+1})} (-1)^i\binom{n-m+1}{i}\binom{m-i\times(k+1)+n-m}{n-m}\)
现在就是要对连续的 \(k+1\) 个球的存在性去容斥,考虑 \(n-m+1\) 个空隙中间,我们枚举一些空隙中有 \(\geq k+1\) 个球,并先放 \(k+1\) 个球进去,之后的黑球随便插入,容易知道每个不合法方案会被计算 \(0\) 次, 由于我们枚举的交界点数量是 \(O(k)\) 的,计算一个 \(ans\) 是 \(O(m/k)\) 的,最后得到一个就是 \(O(m)\) 的。
这个容斥属于不死板的容斥,如果你要对每个起始点容斥就错了,时刻记住,你只需要让不合法计算 \(0\) 遍, 不需要套用任何模板,怎么好钦定怎么容斥。
300iq Contest 1 K. Knowledge
神题,无任何动机可以做出来。
发现把所有的正四面体的状态视作一个群。
\(a\) 视作延中轴转 \(180\degree\), 把 \(b\) 视作延 \(z\) 轴转 \(120\degree\)。
可以发现 aa,bbb,ababab
都不让等价类改变,所有的字符串被划分成 \(12\) 个等价类。
我们要求的就是一个空串不断加 \(a/b\) 最后长度为 \(x\) 的时候和给定串在一个等价类的方案数。
预处理出来等价类加 \(a,b\) 的转移,直接矩阵快速幂即可,复杂度 \(n+12^3 \log x\)
P4709 信息传递
看到这个置换先考虑分解成若干个循环,然后发现单独的一个长为 \(n\) 的循环,\(k\) 次方之后会变成 \((n,k)\) 个长为 \(\frac{n}{(n,k)}\) 的循环,所以肯定是可以循环分解对每个长度分开考虑最后把答案乘起来。
现在我们假设有 \(c\) 个长度为 \(s\) 的循环,那么我们可以用 \(r\) 个拼出来一个大小为 \(rs\) 的循环,当然需要满足 \((rs,n)=r\) , 也就是,我们现在只需要知道 \(r\) 个长度为 \(s\) 的循环,拼出来一个 \(rs\) 的循环的方案数就可以去背包计算答案了。
由于我们要拼出来的是一个环,统计环的数量的关键方法就是钦定一个点。
我们钦定第一个环的起点和大环的起点重合,那么接下来的 \(r-1\) 个循环,可以移动使得任何一个做开头,他们也可以任意排顺序,贡献是 \((r-1)!s^{r-1}\)。
考虑置换环的问题,转化成图上往往很直观,所以大概就是这样
然后就变成了一个简单的图计数类的问题, 设 \(dp_i\) 代表用了 \(i\) 个长度为 \(s\) 的循环,拼出大环的方案数。
\(\displaystyle dp_{i}=\sum_{r, (rs,n)=r} dp_{i-r}\binom{i-1}{r-1} (r-1)!s^{r-1}\) ,经典的钦定选第一个点。
AGC012D Colorful Balls
发现一些点根本就无法交换位置,比如加上同种颜色最小值都 \(> x\) ,加上其他颜色最小值都 \(>y\) 那么我们完全可以把它删掉。
发现删掉他们之后,剩下的都可以随便交换,所以就是一个多重集排列。
CF1630E Expected Components
先求出来总方案,在求出来权值之和即可。
总方案很好求,直接套用 Polya 即可,就是把这些可重集分配到每个环上即可。
权值之和,经典的操作是线性性拆开,发现两个相邻的点,如果颜色并不相同,那么就会有贡献。
枚举颜色 \(x,y\), 贡献就是 \(\displaystyle \binom{(\sum \frac{cnt_i}{d}) - 2}{\frac{cnt_1}{d},\frac{cnt_2}{d},...,\frac{cnt_x}{d}-1,..,\frac{cnt_y}{d}-1,...\frac{cnt_n}{d}}\times \sum \frac{cnt_i}{d} \times d\) .
先把它俩的位置选择出来,再把其他的分配好,由于有 \(d\) 个相同的环,所以贡献有 \(d\) 倍。
发现这个东西就是方案数乘上 \(\frac{cnt_x cnt_y}{(\sum \frac{cnt_i}{d}) (\sum \frac{cnt_i}{d}-1) d^2}\), 剩下的工作就是快速计算 \(\sum_{x\not ={y}} cnt_x cnt_y\), 直接平方和减和平方即可。
P5862 [IOI2015]sorting 排序
先思考一个脑瘫策略,他换一个你给他换回来,这样的话答案就具有单调性,可以考虑二分答案。
然后我们就知道对手做的所有操作了,他每做一个操作我们在他操作的逆操作的基础上做想要的操作,就可以答案忽略它的效果。
所以套用经典结论:交换次数= \(n-\)循环次数, 然后就可以完成 \(check\).
构造方案时刻维护他操作的逆置换即可。
Poj 3270
先考虑最小化次数,也就是所有的代价都相等,那么肯定是直接每个循环内部交换了。
现在考虑代价,先看看每个循环不出去浪的最小代价,因为每个人都要换一次,所以代价至少是 \(\sum val_i+(n-2) minval_k\) , 发现每次让 \(minval_k\) 地方的人换到正确的位置,是可以达到这个下届的。
然后再考虑可以出去换的最小代价,发现肯定是跟全局最小的交换到这个循环里面然后不断交换,代价和上述类似,需要加上把全局最小换进来的代价 \(allminval+minval_k\)
min-max容斥题目
P3175 [HAOI2015]按位或
\(\min-\max\) 容斥对任意一个集合都有效,所以你设计的元素,你生成的集合都适用。
设 \(t_i\) 是第 \(i\) 为变成 \(1\) 的时间,所求就是 \(E(\max t_i)\) ,使用期望下的 \(\min-\max\) 容斥。
\(E(\max t_i)=\sum_{S} (-1)^{|S|+1}E(\min_{i\in S} t_i)\) ,现在就是求出来每个集合内变成 \(1\) 最早的时间的期望。
这个很容易,期望时间是 \(1/\) 一次抽到的概率,一次抽到的概率就是 \(1-\) 一次抽不到的概率。
就是在这个集合的补集的概率之和,使用 FMT/FWT 即可。
P5643 [PKUWC2018]随机游走
首先套用 \(\min-\max\) 容斥,转化成从 \(x\) 第一次进入一个集合 \(S\) 的期望时间。
我们设 \(f_{x,S}\) 代表从 \(x\) 出发开始,第一次进入 \(S\) 的期望时间。
我们处理出来所有的期望时间之后直接把 \(g(S)=(-1)^{|S|+1}f_{x,S}\) ,然后作高位前缀和即可处理出所有答案。
根据定义,显然有转移 \(f_{x,S}=(\frac{1}{\deg_x}\sum_{\{x,y\}\in Edge} f_{y,S})+1\)
我们并不想去高斯消元,所以,使用套路:树上高斯消元。
把每个人都写成关于父亲的函数,即 \(f_{S,i}=A_i f_{S,fa_i}+B_i\) .
为什么可以写成父亲的函数?
对叶节点显然是成立的,然后对于非叶节点归纳即可。
然后递推得到 \(A_x,B_x\) ,由于根节点没有父亲,所以答案就是 \(B_{root}\) 。
Bzoj #4833. [Lydsy2017年4月月赛]最小公倍佩尔数
\(e_n=e_{n-1}+2f_{n-1},f_n=e_{n-1}+f_{n-1}, f_n=f_{n-1}+2\sum_{k=1}^{n-2} f_{k}\)
一类转移类似前缀和的式子,一般都可以通过嵌套变成 O(1) 转移,也就是前缀和优化的过程,这个过程也许可以给这个 dp 更多性质
好的, \(f_{n-1}=f_{n-2}+2\sum_{k=1}^{n-3} f_{k}, f_n=f_{n-1}+(f_{n-1}+f_{n-2})=2\times f_{n-1}+f_{n-2}\)
这里证明了形如 \(f_n=af_{n-1}+bf_{n-2}, \gcd(a,b)=1\) 时都有 \(f_{(a,b)}=(f(a),f(b))\) ,所以我们要把 \(\rm lcm\) 变成 \(\gcd\)
考虑因子上的 \(\min-\max\) 容斥
现在考虑对于 \(n\) 个 \(i\) 计算 \(\sum_{T\in S} [\gcd(T)==i)](-1)^{|T|+1}\), 使用莫比乌斯倍数容斥。
\(F(i)=\sum_{T\in S} [\gcd(T)==i)](-1)^{|T|+1}, G(i)=\sum_{i|d} F(d)\)
有 \(G(i)=\sum_{T\in S} [i|\gcd(T)](-1)^{|T|+1}=\sum_{T\in S} \prod_{j\in T} [i|j](-1)^{|T|+1}\)
也就是说只有一个集合全部都是 \(i\) 的倍数的时候它才会贡献 \((-1)^{|T|+1}\) ,那么我们把所有 \(i\) 的倍数拿出来,那么根据经典的集合反演结论,如果它存在 \(i\) 的倍数,那么就是 \(1\) (注意 \(\min-\max\) 容斥不枚举空集), 否则是 \(0\)。
那么只要 \(i \leq n\) , \(G(i)=1\) , \(F(i)=\sum_{i|d} \mu(\frac{d}{i})G(d)\) 。
我们先 \(n\log n\) 处理出来所有可能的答案变化点 (\(i*j\leq n\) 的 \((i,j)\) 对数变化),然后再做前缀积即可得到答案。
P3598 Koishi Loves Number Theory
知道 \((x^a-1,x^b-1)=x^{(a,b)}-1\) 之后(证明).
再理解一下 \(lcm(\frac{a}{c},\frac{b}{c})=\frac{lcm(a,b)}{c}\) ,gcd,lcm都是可以把公共的提出的。
和上一题一样,并且只用对一个 \(n\) 求答案。
P4707 重返现世
设 \(f_i\) 是得到 \(i\) 这个原料的时间,令 \(k=n-k+1\), 套用 \(kth\min-\max\) 容斥,现在我们只需要求以下式子的值。
我们只需要对每个 \(E(min(S))\) 求出他的系数之和,考虑 \(dp_{i,j,k}\) 代表前 \(i\) 个选了 \(j\) 个 \(\sum p=k\) 的方案数。
考虑去优化这个 \(dp\), 自然是想把 \(j\) 这个东西放到转移里面,容斥系数选的时候变一下就行了,考虑组合数。
由于 \(k \leq 10\), 利用 \(\binom{n}{m}=\binom{n-1}{m}+\binom{n-1}{m-1}\) ,记录一下每个 \(k\) 作为下指标的值即可,复杂度 nmk。
CF Gym 102978H Harsh Comments
定义 \(t_i\) 是 \(i\) 物品被删除的时间,我们要求的就是 \(E(\max_{i\in A} t_i)\)
直接 \(\min-\max\) 容斥之后,我们把答案用期望的线性性拆开,考虑每个物品在所有 \(S\) 集合的物品之前删掉的概率之和。
(这个仍然可以去考虑样本空间, 就是每个样本空间中给在所有 S 集合前面的元素贡献 这个样本的概率, 最后就是对每个元素统计概率了)
然后,拿出第二个经典套路,再只考虑 \(T\) 集合内的先后顺序时,计算概率可以忽略其他元素, 这正是概率的优势所在,也是一些计数题转化成统计概率更简单的原因。
原因就是你可以考虑插入一个无关的元素到所有位置,概率的总和不会变。
所以可以写出计算答案的式子 $\displaystyle \sum_{S\subseteqq A} (-1)^{|S|-1} \sum_{i\not\in S}\frac{val_i}{val_i+sum_S} $
之久好说了,直接把每个 \(S\) 背包背出来,算 \(i\) 的贡献的时候直接退背包即可。
AGC038E Gachapon
设 \(t_i\) 代表 \(i\) 物品有 \(B_i\) 个的时间,那么我们要求的就是 \(E(\max(t))\) .
使用 \(\min-\max\) 容斥,问题变成了如何得到 \(E(\min(S))\)。
当只关心这个集合内的顺序的时候,我们可以直接忽略外面的元素,本质上是利用概率忽略无关元素的性质,现在外面的元素对我们有影响,我们可以手动忽略,强制每次都选到 \(S\) 集合中的元素,最后再给期望乘上 \(\frac{sum}{\sum_{i\in S} A_i}\) , 也就是抽到一个 \(S\) 集合中元素的期望步数。
现在我们只有 \(S\) 集合的元素了,考虑如何统计,最基本的方法是考虑样本空间的每个元素,发现统计一个单点并不容易,此时我们可以大胆尝试,只要设计一个计数方法让任意一个样本的值是它的长度就没问题。
思考发现可以在每个前缀统计一次,假设一个样本的前缀中 \(i\) 被选择了 \(c_i\) 次,也就是对于任意一个 \(\forall i, c_i <b_i\), 我们只需要统计所有这样状态的概率即可,组合数学不难算出 \(\displaystyle \frac{(\sum_{i\in S} c_i)!}{\prod_{i \in S} c_i!} \times \prod (\frac{a_i}{\sum_{i\in S} a_i})^{c_i}\) , 得到计算式之后剩下的工作比较简单,背包把暴力容斥的式子背出来即可, 注意计算复杂度的细节,枚举 \(c_i\) 的总复杂的是 \(\sum b_i\) 的。
CF1687E Become Big For Me
看到 \(\rm gcd, lcm\) 之类的东西一定要想到在指数上变成 \(\min,\max\) 。
然后发现就是每个指数的 \(min+cmin\) , 直接 \(\rm kth-min, max\) 容斥即可。
来简单说一下这个 \(\rm gcd, lcm\) 反演吧,大概就是有很多数要同时取到 \(\min\) ,之后他们每个元素的需求就是 \(\min,\max\) 容斥,结合到一起,多个向量在每个维度上分别取 \(\min\) 就是 \(\gcd\), 分别取 \(\max\) 就是 \(\rm lcm\) , 能合并到一起是因为每个向量的需求都是一样的,在本题中, \(min,cmin\) 是每个因子的需求,由于需求都相同,故可以合并。
现在我们拥有了一个指数算法,只需要如下结论:一个数列的 \(\gcd\) 可以从被这个数列的一个很短的子序列的 \(\gcd\) 表示出来, 具体是多少,反正比 \(\log\) 要小。
具体构造方法如下:先找一个数 \(x\) 包含的本质不同因子数很少,这样,除了 \(x\) 包含的质因子,其他都已经取到 \(\min\), 然后再给每个 \(x\) 包含的质因子的最小的数加上去,这样,就算 \(x=2×3×5×7×11×13×17\) , 也最多需要 \(8\) 个数,我们又一定可以找到一个不影响答案的删掉,正确性容易证明。
在本题,除了 \(\min\), 还要求包含 \(cmin\) , 把 \(\min\) 的 \(7\) 个数找出来之后,再做一遍这个过程,最后就得到了 \(14\) 个数,再对这 \(14\) 个数做这个暴力即可。
UOJ#422. 【集训队作业2018】小Z的礼物
卡特兰数,格路计数题目
ARC145C Split and Maximize
发现肯定是大的根大的配对,现在就是求配对的方案数。
每一对数我们可以先确认谁在前面,然后再把数对出现的顺序固定下来。
最后统计这种限制下的方案发现就是一个卡特兰数, \(2^n n! Cat_n\)
ix35 组合数学例题35
统计从 \((a,b)\) 走到 \((c,d)\),每一步向右或上,且依次经过直线 \(y=a_1+x,y=a_2+x,…,y=a_k+x\) 的方案数(也就是说存在一个路径上点的子序列依次在这些直线上)。
肯定是去考虑不断翻着中点和直线,考虑只有一条直线的时候我们的做法:
若起点和中点在直线一侧,则把终点延直线翻折,计算到达它的方案数, 否则直接统计方案数因为必然经过这条直线。本质是因为,在这条线上,向两边走是等价的,所以可以任意翻折。
基于这个特点,我们把终点也看作一条直线,倒着考虑每一条直线,如果上一条直线和下一条直线在当前的一侧,则延这条直线进行翻折,否则忽略这条直线,注意到,从后往前的过程中,处理过的直线都已经被删除,不再影响答案。
必然经过等价于一个新起点,要利用从此开始等价的性质
NOI模拟5.14 A
首先可以考虑怎么判断一个颜色序列是否合法,是做计数题的第一步。
发现直接拿一个栈,和栈顶相同就贪心的弹走,这样匹配是不劣的,然后可以写一个暴力 dp 模拟这个过程去计数,也就是有 \(k-1\) 种方法加入一个元素,有 \(1\) 种方法删除一个元素,但是有一个特例,当元素个数为 0 的时候有 \(k\) 种方法加入一个元素。
也就是,我们求出来有 \(t\) 次空栈的进出栈序列的数量,乘上 \(k^t(k-1)^{n-t}\) 就是答案,这就是 \(Cat_k\)。
P3266 [JLOI2015]骗我呢
发现关键性质之严格递增,也就是题目的意思是让我们选择一个序列,每个数要大于等于上一个数减一。
这个时候可以写出一个 nt 的 dp, \(dp_{i,j} = \sum_{k\leq j+1} dp_{i-1,k}\)
一类转移类似前缀和的式子,一般都可以通过嵌套变成 O(1) 转移,也就是前缀和优化的过程,这个过程也许可以给这个 dp 更多性质
然后,令 \(f_{i,j}=sum_{k\leq j} dp_{i,j}\) , 有 \(f_{i,j}=f_{i,j-1}+f_{i-1,j+1}, ans=f_{n,m}\)
转化成格路计数,就是从 \((0,0)\) 每次向上或者向右,不接触 \(y=x+1, y=x-(m+2)\) 到达 \((n+m+1,n)\) 的方案数。
求这个可以考虑容斥,一开是我有一个 naive 的想法,用直接走-接触一个+接触两个,接触两个分成先接触 \(A\) 再接触 \(B\) 和先接触 \(B\) 再接触 \(A\)。
前两个倒是好说,求最后一个的时候我是先把终点延 \(A\) 翻折再把终点延 延 \(A\) 翻折的 \(B\) 翻折。
这样确实可以保证接触了 \(A,B\) ,但根本保证不了先接触 \(A\) ,那么我们就继续容斥,在容斥 \(BAB\) , 减去不先接触 \(A\) 的 \(AB\) 型路径。
如此一直容斥下去就是答案,因为翻折会让终点变的偏,所以总容斥次数是有限的。
P4769 [NOI2018] 冒泡排序
先观察得到如果存在 \(a,b,c\) 满足 \(a>b>c\) ,那么一定会有浪费的步,所以好的序列就是最长下降子序列不超过 \(2\) 的序列。
然后可以写一个 nt 的 dp, \(dp_{i,j,k}\) 代表考虑前 \(i\) 个数,第 1 个上升子序列的结尾排名是 \(j\) , 第 2 个上升子序列的结尾排名是 \(k\), 发现 \(j,k\) 必定有一个是 \(i\), 故省略。
在序列中插入一个数,容易得到转移, \(dp_{i,j}=\sum_{k\leq j} dp_{i-1,k}\)
按照套路写成前缀和简化 dp 柿子,有 \(dp_{i,j}=dp_{i,j-1}+dp_{i-1,j}\), 满足 \(j \leq i\) 。
不考虑字典序直接一个卡特兰就完了,考虑字典序,枚举 lcp, 得到目前的 dp 状态,然后是一个 \(f_{i,k \geq j}\) 设置成 \(1\), 转移到 \(f_{n,n}\) 的方案数,同样在坐标系上走,可以把 \(f_{i,k \geq j}\) 简化成 \(f_{i-1,j}\) , 转移系数一样算。
JAG2018 Day2-K Short LIS
ARC068D Solitaire
Alex_wei 组合数学例题6.2I
题意简述:一个人在数轴 n 处,每次有一半的概率向左或向右走,求在 k 步以内经过原点的概率对 998244353 取模。\(1≤n,k≤5×10^6\)。
P6689 序列
CF1204E Natasha, Sasha and the Prefix Sums
CF896D Nephren Runs a Cinema
Uoj #424. 【集训队作业2018】count
P4260 [Code+#3]博弈论与概率统计
ARC061D Card Game for Three
AGC019F Yes or No
AGC040F Two Pieces
ARC128F Game against Robot
CFgym102978C Count Min Ratio
AGC030F Permutation and Minimum
Alex_wei 组合数学例题6.2II
题意简述:用 n 个 1 和 m 个 0 构造序列使得任何子区间包含的 0,1 个数相差不超过 k,计数。\(n+m,k≤5×10^7\)。
斐波那契题目
BZOJ2813 奇妙的Fibonacci
CF446C DZY Loves Fibonacci Numbers
CF226C Anniversary
CF718C Sasha and Array
NOIP模拟81C 斐波
CF316E3 Summer Homework
Gym #101161G - Binary Strings
斯特林数题目
TopCoder 14199 CyclesNumber
基本的恒等式运用, \(\displaystyle \sum_{i=1}^n\begin{bmatrix}n \\ i \end{bmatrix} i^m=\sum_{i=1}^n \begin{bmatrix} n \\ i\end{bmatrix}\sum_{j=0}^i\begin{Bmatrix} m \\ j\end{Bmatrix} i^{\underline{j}}=\sum_{j=0}^n \begin{Bmatrix} m \\ j\end{Bmatrix} \sum_{i=j}^n\begin{bmatrix} n \\ i \end{bmatrix} i^{\underline{j}}=\\ \displaystyle \sum_{j=0}^n \begin{Bmatrix} m \\ j\end{Bmatrix} j!\sum_{i=j}^n\begin{bmatrix} n \\ i \end{bmatrix} \binom i j=\sum_{j=0}^n \begin{Bmatrix} m \\ j\end{Bmatrix} j!\begin{bmatrix} n +1\\ j+1\end{bmatrix}\)
然后可以直接处理 \(nm\) 个第一类, \(m^2\) 个第二类之后直接计算。
用组合数代替下降幂是常用套路,给恒等式带来更多可能性。
P6620 [省选联考 2020 A 卷] 组合数问题
\(\displaystyle \sum_{k=0}^nf(k) \times x^k \times \binom n k\) 这种柿子直接没法算,考虑把多项式拆开,枚举每个次数。
\(\displaystyle \sum_{k=0}^nf(k) \times x^k \times \binom n k= \sum_{k=0}^n (\sum_{j=0}^ma_jk^j) \times x^k \times \binom n k=\sum_{j=0}^m a_j \sum_{k=0}^nk^jx^k\binom n k\)
这里一个常用套路是把 \(k^j\) 这个东西用斯特林展开,这样就有了另外一个上界,注意尽量展开我们可以操作组合的 \(k\) 次幂。
\(\displaystyle \sum_{j=0}^m a_j \sum_{k=0}^nk^jx^k\binom n k=\sum_{j=0}^m a_j \sum_{k=0}^nx^k\binom n k\sum_{t=0}^k \binom k t t!\begin{Bmatrix} j \\ t\end{Bmatrix}=\sum_{j=0}^m a_j\sum_{t=0}^j \begin{Bmatrix} j \\ t\end{Bmatrix} t!\sum_{k=t}^n\binom n k \binom k t x^k\)
枚举 \(j,t\) 是 \(m^2\) 的,可以接受,我们只需要考虑快速计算
\(\displaystyle \sum_{k=t}^n\binom n k \binom k t x^k= \binom n t \sum_{k=0}^n \binom {n - t} {k - t}x^k=\binom n t \sum_{k=t}^n \binom {n - t} {k - t}x^k=\binom n t x^t\sum_{k=0}^{n-t} \binom {n - t} {k}x^k=\binom n t x^t(x+1)^k\)
CF932E Team Work
基本转化是和上一题一样的手法
\(\displaystyle\sum_{i=1}^n\binom n i i^k=\sum_{i=1}^n \binom n i \sum_{t=0}^i\binom{i}{t} t! \begin{Bmatrix} k \\ t\end{Bmatrix}=\sum_{t=0}^k\begin{Bmatrix} k \\ t\end{Bmatrix}t!\sum_{i=t}^n\binom n i \binom i t= \\ \displaystyle \sum_{t=0}^k\begin{Bmatrix} k \\ t\end{Bmatrix}t!\binom n t\sum_{i=t}^n\binom {n-t}{i-t}=\sum_{t=0}^k\begin{Bmatrix} k \\ t\end{Bmatrix}t!\binom n t 2 ^{n-t}\)
此时停手已经可以计算了,但是快速计算一行斯特林我不会。
这里还有一个人畜无害的 \(\begin{Bmatrix} k \\ t \end{Bmatrix} t!\) 考虑把它展开,我们继续化简柿子。
\(\displaystyle \sum_{t=0}^k\begin{Bmatrix} k \\ t\end{Bmatrix}t!\binom n t 2 ^{n-t}=\sum_{t=0}^k \binom n t2^{n-t}\sum_{j=0}^t(-1)^{t-j}\binom t jj^k=\sum_{j=0}^nj^k \sum_{t=j}^k\binom n t \binom t j2^{n-t}(-1)^{t-j}=\)
\(\displaystyle 2^n \sum_{j=0}^nj^k (-1)^j \sum_{t=j}^k\binom n t \binom t j(-\frac{1}{2})^{t}=2^n \sum_{j=0}^nj^k (-1)^j \binom n j \sum_{t=j}^k\binom {n-j} {t- j}(-\frac{1}{2})^{t}=\)
\(\displaystyle 2^n \sum_{j=0}^nj^k (-1)^j \binom n j (-\frac{1}{2})^j\sum_{t=0}^{k-j}\binom {n-j} {t}(-\frac{1}{2})^{t}=\sum_{j=0}^nj^k 2^{n-j} \binom n j \sum_{t=0}^{k-j}\binom {n-j} {t}(-\frac{1}{2})^{t}\)
令 \(\displaystyle f(j)=\sum_{t=0}^{k-j}\binom {n-j} {t}(-\frac{1}{2})^{t}\) ,\(f(j)\) 是经典的关于 \(j\) 的递推式,可以 \(O(n)\) 把 \(n\) 个都求出来。
具体的,每次我们把组合数展开,然后凑到 \(f(j)\) 上即可,下指标求和可以递推。
CF1278F Cards
枚举看到几张王牌,可以列出柿子 \(\displaystyle \sum_{i=1}^n i^k \binom n i (\frac 1 m)^i(\frac{m-1}m)^{n-i}\) 。
然后和上一题完全一致的手法可以做到 \(O(n)\) ,可以拿来练手,这里不再展开。
CF961G Partitions
考察每个元素对答案的贡献,枚举这个元素所在集合大小。
$\displaystyle \sum_{i=1}^n w_i\sum_{j=1}^n j \binom {n-1}{j-1} \begin{Bmatrix} n - j \ k - 1\end{Bmatrix} = (\sum_{i=1}^n w_i) \times (\sum_{j=1}^n j \binom {n-1}{j-1} \begin{Bmatrix} n - j \ k - 1\end{Bmatrix}) $ 考虑怎么快速计算后面的部分。
考虑这个柿子的实际意义,把 \(n\) 分成 \(k\) 个集合,贡献是包含一号点的集合大小。
注意到这个问题里面所有的点是没有区别的,所以我们不妨统计包含每个点的集合大小之和,最后除以 \(n\) 就是答案。
重新审查,对于一种方案贡献是 \(\sum siz^2\) , \(siz\) 是每个联通块的大小。
对于 \(\sum x^2\) 有一个经典的套路就是考虑每一对点( \((x,x)\) 也是合法的 )的贡献。
分开考虑 \(x=y\) 和 \(x!=y\) , \(x=y\) 的时候,任意一种划分方案都有贡献,故 \(x,x\) 的总贡献是 \(n*\begin{Bmatrix} n \\ k\end{Bmatrix}\)
\(x!=y\) ,那么 \(x,y\) 必须在一个集合才有贡献,我们直接把 \(x,y\) 捆绑成一个元素,那么所有 \(x,y\) 的总贡献是 \(n*(n-1) \begin{Bmatrix} n - 1\\ k\end{Bmatrix}\) ,故答案是 \(\frac{n*\begin{Bmatrix} n \\ k\end{Bmatrix}+n*(n-1) \begin{Bmatrix} n - 1\\ k\end{Bmatrix}}{n}=\begin{Bmatrix} n\\ k\end{Bmatrix}+(n-1) \begin{Bmatrix} n - 1\\ k\end{Bmatrix}\) 直接 \(O(n)\) 算一个斯特林数即可。
CF1342E Placing Rooks
不难发现必须每行都有或者每列都有一个才能合法,计算每行都有一个的, \(\times 2\) 就是答案 (\(k=0\) 需要特判)。
我们需要 \(k\) 对能互相攻击的车,观察一下发现肯定 \(k<n\) ,故搬出经典结论之 联通块数=点数-边数。
所以, 我们肯定是有 \(n-k\) 个联通块,也就意味着只有 \(n-k\) 列有车,答案就是 \(\binom n {n-k} (n-k)! \begin{Bmatrix}n \\ n - k\end{Bmatrix}\)
观察出来有 \(n-k\) 个联通块是合法的充要条件就结束了。
CF960G Bandit Blues / P4609 [FJOI2016]建筑师
(需要快速求 一行/一列 斯特林数)
先考虑只有一个限制如何做,排列计数优先考虑插入, \(f_{i,k}\) 代表前 \(i\) 个数 \(k\) 个前缀最大值的方案数。
转移有 \(f_{i,k}=f_{i-1,k}*(i-1)+f_{i-1,k-1}\) 分别代表插入一个非最大值或者最大值,发现 \(f\) 就是第一类斯特林数。
为什么他恰好是第一类斯特林数?
考虑第一类斯特林数的本质,给每一种集合划分统计 \(\prod (siz-1)!\) 次。
现在我们要 \(k\) 个前缀最大值,那就先划分成 \(k\) 个集合,然后把这 \(k\) 个集合的最大值放在最前面。
每个集合除了最大值的部分任意排列,可以统计 \((siz-1)!\) 次, 这 \(k\) 个集合按照最大值排序即可恰好对应几个序列。
且每个序列都可以通过这个方法映射到一个集合的划分。
然后考虑两个限制,观察一下发现前面后面的唯一交集就是全局最大值,故直接枚举它在哪。
答案就是 \(\displaystyle \sum_{k=1}^n \begin{bmatrix} k - 1 \\ A - 1\end{bmatrix}\begin{bmatrix} n -k \\ B - 1\end{bmatrix} \binom {n-1}{k-1}=\binom{A+B-2}{A-1} \begin{bmatrix} n - 1 \\ A +B- 2\end{bmatrix}\) ,恒等式证明 。
CF838D Airplane Arrangements
记录一下这个模型吧,感觉很神仙。
首先题意就是让我们从任意一个位置,任意选择一个方向开始走,走到第一个空位置坐下。
根本没有什么有效的 \(dp,\) 容斥的方式,考虑 泛化元素 : 让所有元素变得等价,达到缩小 dp 状态,或者等概率使用概率计数。
链上显然是不等价的,但是我们拼接成环,他就等价了,现在每个人都能在环上选择任意一个方向走,找到第一个空位置坐下。
但是我们怎么判断合法呢? 考虑 添加一个失败节点 ,在 \(1,n\) 之间加入一个 \(n+1\) ,如果他是空的就是合法。
注意为了让 \([1,n+1]\) 这些节点全部等价,我们需要让角色任意选择 \([1,n+1]\) 中的一个节点在选择一个方向走。
合法的概率就是 \(n+1\) 空着的概率,由于每个元素等价,所以 \(=\frac {n + 1 -m} {n+1}\) ,乘上总方案 \((2\times(n+1))^m\) 就是答案。
- 本题的两个套路:泛化元素变成等价使用概率计数,添加失败节点,把状态也泛化成元素。
CF1528F AmShZ Farm
(需要快速求 一行/一列 斯特林数)
计数题实在走投无路,可以考虑转化计数对象,建立双射
先把 \(a\) 数组合法的条件转化成从 \(a_i\) 开始走,走到第一个空的坐下,然后套用上题模型,合法\(a\) 有 \((n+1)^{n-1}\)。
继续发掘性质,这个题比上一个题还多了一个性质:只有一个空位。
并且我们发现,所有的 \(a_i\) 在 \([1,n+1]\) 的域上加一 (\(x\rightarrow(x-1) \mod (n+1)+1\)) ,那么空位也会动 \(1\) 。
并且我们移动它的过程,它对应的合法的 \(b\) 的数量不变,所以我们计算所有可能的 \(a\) 对应的 \(b\) 的数量,除以 \(n+1\) 就是答案。
由于所有的点 \([1,n+1]\) 是等价的,我们计算一个点的贡献乘 \(n+1\) 就是总贡献。
一个点的贡献,直接枚举他有几个 $\sum_{i=1}^n \binom n i n^{n-i} i^k $ 选出来他的位置,剩下的 \(n-i\) 个位置可以随意放置剩下的 \(n\) 个数。
这个柿子可以用和上面的题类似手法变成斯特林数,快速计算一行即可。
CF1644F Basis
发现不用操作一,那么一个序列能否表示只跟他的集合划分有关,需要的次数是 \(\sum \begin{Bmatrix} n \\ i\end{Bmatrix}\)。
考虑有操作一,那么就是 aaaa|bbbb|cccc|dddd|,,,
这种东西可以被操作一操作出来。
形式化的,去掉最后一个连续段,我们只需要统计所有连续段 \(\gcd \not= 1\) 的。
那就直接枚举 \(\gcd\) 去容斥,容斥的原因是斯特林分配的时候只能保证 \(\gcd\) 是他的倍数。
\(\displaystyle Ans = \sum_{i=1}^n \mu(i) ((\sum_{j=1}^k\begin{Bmatrix} \lceil \frac{n}{i} \rceil \\ j \end{Bmatrix})-1)\) 。
减一的原因是 \(j=1\) 时候整个段只有一个颜色,没有出去最后一个段的段,集合是空集不存在所谓的 \(\gcd\) .
问题落到了如何快速的求斯特林的前缀和,这里有一个 \(O(k)\) 计算 \(\begin{Bmatrix} n \\ k \end{Bmatrix}\) 的前 \(k\) 项的方法,那么总复杂度就是 \(\sum \lceil \frac{n}{i}\rceil=O(n\ln n)\)。
直接把 \(O(k)\) 算一个 \(\begin{Bmatrix} n \\ k \end{Bmatrix}\) 的柿子写出来
\(\displaystyle \sum_{k=0}^t\begin{Bmatrix} n \\ k \end{Bmatrix}=\sum_{k=0}^t\frac{1}{k!}\sum_{i=0}^k(-1)^{k-i}\binom k i i^n=\sum_{k=0}^t\sum_{i=0}^k \frac{(-1)^{k-i}}{(k-i)!} \times \frac{i^n}{i!} =\sum_{i=0}^t \frac{i^n}{i!} \sum_{k=i}^t\frac{(-1)^{k-i}}{(k-i)!}\)
处理后面东西的前缀和,每次枚举前面的东西即可, \(i^n\) 需要使用线性筛。
ARC096E Everything on It
考虑去容斥第二个条件,枚举至少有 \(i\) 个调料出现 \(\leq 1\) 次。
我一开始先考虑的 \(\leq 0\) 次,是很简单的,因为他们不能有, \(\leq 1\) 次,就要观察他的特殊性质。
性质就是他本身,这些调料出现 \(\leq 1\) 次,那么我们可以把他们分到一些面上,因为它们永远不会成为两碗面的交集。
我们开一个“垃圾桶”来放出现 \(0\) 次的,由于必须非空,我们在开一个垃圾球,钦定垃圾球在的盒子是垃圾桶。
那么,把 \(k\) 个 \(\leq 1\) 次的调料分配到 \(t\) 个面里,方案数是 \(\begin{Bmatrix} k +1\\ t+1\end{Bmatrix}\)。
或者直接推柿子也是可以的,我们可以枚举有多少个调料出现 \(0\) 次, \(\displaystyle \sum_{i=0}^k \binom k i\begin{Bmatrix} k - i \\ t\end{Bmatrix} = \begin{Bmatrix} k + 1\\ t+1\end{Bmatrix}\)
然后这 \(t\) 个面可以在 \(2^{n-k}\) 个合法的调料里面任意选择,由于他们已经被 \(k\) 个不合法的调料区分了,所以不用担心他们会相同。
方案数 \((2^{n-k})^j\) ,剩下的 \(2^{n-k}\) 种不包含这个集合的面,每种都可以选择出现与否。
所以答案是 \(\displaystyle \sum_{i=0}^n(-1)^i \binom n i 2^{2^{n-i}}\sum_{t=1}^i \begin{Bmatrix} i + 1 \\ t + 1\end{Bmatrix} (2^{n-i})^t\)
ARC106F Figures
直接枚举度数序列 \(\displaystyle \sum_{\{deg| \sum deg_i=2n-2\}} \binom {n-2}{deg_1-1,deg_2-1,...,deg_n-1} \prod d_i^{\underline{deg_i}}\)
着急化简就错了,考虑多元二项式定理的下降幂形式。
感觉比较实用的证明二项式定理的组合意义方法
当年被归纳骗的一愣一愣的。
先考虑普通幂的形式,组合意义就是在 \(\sum a_i\) 个盒子里面放 \(n\) 个球。
我们枚举在 前 \(a_1\) 个盒子里面放了多少球,再枚举 \((a_1,a_2]\) 里面放了多少球 ...
再选出来放到 \(a_1,a_2,...,a_n\) 的球是啥,就成功证明了。
下降幂形式是类似的,不过就是一个盒子只能放一个球选出来之后也保证一个盒子只能放一个球即可
发现把 \(\prod d_i\) 提取出来,剩下的柿子 \(\displaystyle \sum_{\{deg| \sum deg_i=2n-2\}} \binom {n-2}{deg_1-1,deg_2-1,...,deg_n-1} \prod (d_i-1)^{\underline{deg_i-1}}=(\sum d_i-1)^{\underline{\sum deg_i-1}}=(\sum d_i-1)^{\underline{n-2}}\)
于是就做完了? 确实。
CF gym102222M
由图着色的知识可以知道 无环定向方案数= \(X(G,-1)*(-1)^n\) ,那么求出来 \(X(G,k)\) 的表达式即可。
这是很简单的,由于是完全二分图,那么就直接枚举左边用了多少颜色。
带入 \(k=-1, \displaystyle Ans=(-1)^{n+m}\sum_{c=0}^n \binom {-1} c c!\begin{Bmatrix} n \\ c \end{Bmatrix} (-1-c)^m\)
带入组合数的定义 \(\binom n m = \frac{n^{\underline{m}}}{m!}\) 得到 \(\binom {-1} c = (-1)^c*\frac{c!}{c!}=(-1)^c\)
快速计算一行斯特林数即可。
Uoj #144. 【UER #5】万圣节的糖果
炫酷双射,没做出来。
先考虑一种最终的集合划分,除了每个集合最大的数之外,每个数都有一个后继,就是这个集合内第一个大于他的数,且必定和他奇偶性不同。
不同这个很难去满足,考虑把每个数的后继都向后平移一位,具体的,原本 \(i\) 的后继是 \(x\) ,现在让他是 \(x+1\)。
这么一番变换之后,有 \(n+1\) 个数,而由于之前最大的数还拥有一个集合,而 \(n+1\) 也拥有了一个集合,现在有 \(m+1\) 个集合,每个集合内的数奇偶性相同。
随便拿来一个 \(n+1\) 划分成 \(m+1\) 个集合,每个集合内的数奇偶性相同的方案,也有逆变换换成一个符合条件的集合,所以他是双射。
双射之后的东西容易统计,直接枚举有几个奇数的集合,然后斯特林数即可。
P4827 [国家集训队] Crash 的文明世界
\(k=1\) 就是换根 dp 的模板, 然后发现我们需要递推的是 \(\sum{a}^k \rightarrow \sum(a+1)^k\) 。
有一个简单的想法是把 \((a+1)^k\) 二项式展开,状态 \(nk\) 转移 \(k\) ,复杂度 \(nk^2\) 。
递推 \(x^k\) 有一个套路就是把它用斯特林数展开, \(\sum dis(x,i)^k=\sum dis(x,i) \sum_{t=0}^k \begin{Bmatrix} k \\ t \end{Bmatrix}t!\binom{dis(x,i)}t=\sum_{t=0}^k t!\begin{Bmatrix} k \\ t \end{Bmatrix}\sum \binom{dis(x,i)}{t}\) 。
所以我们就是想要计算 \(\sum \binom{dis(x,i)} t\) ,设 \(f_{x,t}\) 代表 \(x\) 子树内选择了 \(t\) 条边方案数。
每次合并考虑选或不选可以 \(f_{x,t}*f_{y,z} \rightarrow f_{x,t+z+1} / f_{x,t+z}\) 。
第一遍 dp 可以求出子树内的,考虑换根求出子树外的,从 \(fa\) 转移的时候把 \(fa\) 子树内和 \(fa\) 子树外分开讨论,子树内容斥一下转移,就是加上 \(fa\) 子树内的 \(dis+1\) 减去 \(x\) 子树内的 \(dis+2\) ,具体的解释。
NOI 模拟7.5 T3 树论
CF809E Surprise me! + P4827 [国家集训队] Crash 的文明世界 强行二合一。
GDOI2018 滑稽子图
题目大意:对于一棵树 \((V,E)\),对于 \(S⊂V\) ,\(f(S)\) 为点集 \(S\) 的导出子图的边数。求 \(∑_{S⊂V}f(S)^k\)
这里的导出子图说的是,点集为 \(S\) ,边集为 \(\{(u,v)∈E|u,v∈S\}\) 的一个子图。
一样的斯特林展开 \(k\) 次方,考虑怎么求一个导出子图内选择了 \(k\) 条边的方案数。
直接树形 dp, \(f_{x,y,0/1}\) 代表 \(x\) 子树内, 选择了 \(y\) 条边, \(x\) 是否选择的方案数。
转移,如果 \(x,son_x\) 可以选择那么讨论选不选择转移,否则直接转移。
CF1097G Vladislav and a Great Legend
同样的斯特林展开后变成求所有情况的虚树内选择 \(k\) 条边的方案数, 记为 \(ans_i\)。
注意到一种虚树不一定包含 \(1\) ,所以我们要在每个虚树的根统计答案。
转移的时候分为两种,一种是合并两个子树,这种转移要顺便贡献到答案里面。
还有一种是沿用原来的,这种根还没有确定,所以不能贡献到答案。
证明一下树形背包第二维和 \(k\) 取 \(\min\) 的复杂度,分合并两个子树之后 \(>k\) 和 \(\leq k\) 分类讨论。
合并之后 \(>k\) 这样的合并一次 \(k^2\) ,最多发生 \(n/k\) 次,因为最多 \(n/k\) 个大子树。
合并之后 \(\leq k\) ,这样合并的复杂度是 \(siz_x*siz_y\) ,考虑每个极大的 \(\leq k\) 的子树,它内部最多有 \((siz)^2\) 的贡献,且这些子树的 \(\sum siz\leq n\) ,我们要最大化 \(\sum_{\sum siz_i=n, \forall siz_i \leq k} (siz_i)^2\) ,不难发现这个东西最大是 \(nk\) 在 \(n/k\) 个 \(siz=k\) 的时候取到,因为 $a2+b2\leq (a+b)^2 $ 。
TopCoder 13444 CountTables
联通块容斥的真正面目是斯特林容斥!
首先,在 容斥 这篇博里,我们介绍了关于“在不要求互不相等时容易计算,如果要求互不相等该怎么计算”, 并用边集容斥和图计数的知识证明了它,现在,我们从斯特林反演的角度解释它的本质。
我们首先得到不要求列互不相等时的计算公式 \((C^m)^{\underline{n}}\) ,每行都有 \(C^m\) 种选择,唯一要求是和之前不同。
我们考虑两行之间相等,就在他们之间连一条边,从而导出经典的 polya 容斥,他的意义是一种联通块划分贡献是 \(\displaystyle \prod (-1)^{siz - 1} (siz-1)!\) ,接下来,让我们考虑所有有 \(k\) 个联通块的情况对答案的总贡献。
首先 \(\displaystyle \prod( -1)^{siz-1}\) 的总贡献肯定是 \((-1)^{n-k}\) ,接下来考虑 \(\prod (siz-1)!\) 对答案的贡献,发现他就是把图划分成 \(k\) 个联通块,每个联通块选一个圆排列(选法恰好是 \((siz-1)!\)),熟练的选手已经知道了,没错,第一类斯特林数。
所以,根据 polya 容斥进行扩展,我们得到图中有 \(k\) 个联通块对答案的总贡献是 \(\begin{bmatrix} n \\ k \end{bmatrix} (-1)^{n-k}\) 。
如此熟悉的面孔,不如我们再从斯特林反演的角度去思考他。
设 \(F_m\) 是恰好 \(m\) 个联通块的方案数 , \(G_m\) 是已经形成 \(m\)个联通块 ,块之间还有可能连边的方案数。
根据定义,我们得到 \(\displaystyle G_m =\sum_{i=0}^m \begin{Bmatrix} m \\ i\end{Bmatrix}F_i\) ,\(m\) 个联通块之间任意连边有 \(\begin{Bmatrix} m \\ i \end{Bmatrix}\) 种方案变成 \(i\) 个联通块。
进行斯特林反演,得到 \(\displaystyle F_m=\sum_{i=0}^m \begin{bmatrix} m \\ i \end{bmatrix}(-1)^{m-i}G_i\) 和我们用 polya 容斥推出的相同。
polya 容斥 和 斯特林容斥 之间的关系就像子集反演和二项式反演的关系一样,在我们方便加入一个联通块的时候,我们可以选择用 dp 去求 polya 的容斥系数,在我们方便知道钦定 \(i\) 个联通块的贡献的时候, 斯特林容斥是更好的选择。
回到本题,一种钦定 \(i\) 个联通块的贡献是 \((C^i)^{\underline{n}}\) ,直接斯特林容斥即可。
带边数的无向连通图计数
题目简意:给定 \(n,m\) , 要求 \(n\) 个点 \(m\) 条边的无向连通图的个数, \(n\leq 100, m\leq \frac{n*(n-1)}{2}\)
发现暴力做是 \(n^6\) 的,我们需要一个 \(n^4\) 算法,主要是保证恰好一个联通块比较麻烦,考虑容斥。
\(F_i\) 代表钦定 \(i\) 个块之间互不连边,但是每个块内部任意连边不保证联通的方案数, \(G_i\) 代表恰好 \(i\) 个联通块的方案数。
考虑斯特林反演之 \(\displaystyle F_{n}=\sum_{i=n} \begin{Bmatrix} i \\ n \end{Bmatrix} G_i \Leftrightarrow G_n=\sum_{i=n} (-1)^{i-n} \begin{bmatrix} i \\ n \end{bmatrix} F_i\) ,我们需要求 \(\displaystyle G_1=\sum_{i=1} (-1)^{i-1}(i-1)!F_i\) 。
我们发现 \(m\) 条边可以在每个联通块内部任意选择,也就是我们只需要知道一种联通块划分种有几个联通块以及 \(\sum\binom {siz}2\) ,就可以计算贡献,考虑设 \(H_{i,j,k}\) 代表考虑了前 \(i\) 个点,有 \(j\) 个联通块, \(\sum\binom{siz}2=k\) 的划分方案数,转移枚举一个包含最小点的联通块,复杂度 \(O(n^5)\) 。
考虑优化掉 \(j\) 这一维,经典操作就是在 \(dp\) 的时候加入系数, \((-1)^i\) 到是好说,第一个钦定系数是 \(1\) ,后面加入一个带 \(-1\) 的系数。
考虑钦定包含最小点是怎么让我们不重复计数的,这里有一个最终的方案,我们每次删除一个包含最小点的联通块,一种方案只有一种删除的方法。
在 \(dp\) 的时候加入阶乘是经典难题,但是这题却有特殊的性质,考虑我们加入一个联通块时候不钦定必须包含最小的点,那么每种方案没被计算 \(j!\) 次, \(j\) 是这种划分方案的联通块个数,因为一种方案,我们每次删掉任意一个联通块有 \(j!\) 种删法,然后递归下去继续删,那么任意一种排列的方案都能删除出来。
类似的,我们设计一个一种方案会被计算 \((j-1)!\) 的方案:对于一种方案,我们每次选择任意一个不包含 \(1\) 的联通块删掉,然后递归下去继续删,那么一种方案有 \((j-1)!\) 种计算的方案。
考虑怎么把不包含 \(1\) 应用到转移上:每次在 \(2-(i+k)\) 选择出来 \(k\) 个点即可,为了最初不乘 \(-1\) 的系数,我们需要特殊进行初始化。
可以配合代码理解
void DP()
{
for(int i = 1; i <= n; ++i)
H[i][c2(i)] = 1;
for(int i = 1; i <= n; ++i)
for(int j = c2(i); j >= 0; --j)
if(H[i][j])
for(int k = 1; i + k <= n; ++k)
H[i + k][j + c2(k)] = (H[i + k][j + c2(k)] - 1ll * H[i][j] * C[i + k - 1][k]) % mod;
for(int j = 0; j <= c2(n); ++j)
{
for(int k = j; k <= c2(n); ++k)
F[j] = (F[j] + 1ll * H[n][k] * C[k][j]) % mod;
F[j] = (F[j] + mod) % mod;
printf("%d\n", F[j]);
}
}
从钦定包含最小的点到钦定不包含 \(1\) ,这种题目数不胜数,要想都做来不太现实,还有许多这样需要你自己配置计算系数还解决或者优化问题的题目,最重要的就是考虑一种最终的 Dp 方案,设计一个计算它你需要遍的方案,才是永恒的套路。
Bzoj #4671. 异或图
看到要求图联通就可以考虑去容斥,经典的斯特林容斥之后,现在要求的变成了有多少个子集可以异或出来钦定 \(i\) 个块不连通的方案。
发现非常难入手,所以, 人有多大胆,题有多简单! ,我们何必为苦子集枚举有几个联通块? 我们直接枚举联通块划分,复杂度 \(Bell\) 数, \(Bell(10)=115975\) ,甚至 \(Bell(12)=4213597\) 都是可接受的,爆搜就直接枚举当前元素加入到第一个集合里面,或者新开一个集合。
群论里我们有枚举划分数的算法,估约复杂度 \(e^{\sqrt \frac{20n}{3}}\),数论里面我们也有枚举约数的算法,复杂度 \(n^{\frac{1.066}{lnlnn}}\) 。
发现枚举完联通块划分之后变得异常简单,他们在线性基内不能连的边,必须要求异或出来是 \(0\) ,其余的无要求,我们可以只拿出来有要求的边,然后都尝试插入线性基,最终异或出来 \(0\) 的方案就是 \(2^{s-|B|}\) 。
欧拉数题目
CF1349F1 Slime and Sequences (Easy Version)
牛逼题,构造双射。
我们发现题目的限制相当于 \(i\) 的第一次出现 \(<i+1\) 的最后一次出现。
此时还是没有什么头绪,不妨考虑把他写出来看需要满足什么。
我们把每个数 \(i\) 的第一次出现位置记为 \(L_i\) ,最后一次出现记为 \(R_i\) 。
把它按这样接起来,发现了他们之间全都是 \(<\) 。
出现位置,小于号,你想到了什么?
没错,把 \(R,L\) 之间 \(i\) 的每次出现位置都补齐,那么他就是一个有 \(i-1\) 个小于号的排列的数量。
所以每个好序列唯一对应一个排列,接下来考虑计算 \(i\) 的贡献。
我们枚举 \(i\) 贡献的位置 \(pos\) ,就是要保证 \(pos\) 之前有 \(i-1\) 个段,后面可以任意放。
所以 \(\displaystyle Ans_i=\sum_{j=1}^n\left\langle \begin{matrix} j \\ i-1\end{matrix}\right\rangle \binom n {n-i} (n-i)!\) 直接 \(n^2\) 计算即可。
P7511 三到六 (\(n^2\) only Version)
拆成若干个环,计算每个环的贡献,最后暴力卷积起来即可。
考虑如何计算一个 \(n\) 个点的环有 \(k\) 个升高的方案数。
一种想法是利用 \(O(n)\) 算一个欧拉数的容斥,就是分配的时候是 \(\begin{Bmatrix} n \\ n - i \end{Bmatrix}(n-i-1)!\) (联通块只能圆排列),复杂度是 \(n^3\)。
不妨考虑破环为链,枚举一下 \(1\) 的位置,那么他肯定回产生一个上升,剩下的直接 \(\left\langle \begin{matrix} n - 1 \\ k - 1\end{matrix}\right\rangle\) 。
由于有 \(n\) 个可以放的地方,所以答案就是 \(n*\left\langle \begin{matrix} n - 1 \\ k - 1\end{matrix}\right\rangle\)
Polya 容斥
ABC236 Ex
如果不要求每个数互不相等,那么答案很容易计算,对于这类题,有一个套路的容斥(貌似叫 \(polya\) 容斥)。
先考虑最暴力的容斥,假设 \(a_i, a_j\) 相等,就在 \(i, j\) 之间连一条边。
最后我们要的是 \(0\) 条边的方案数,那么我们 \(2^{\binom n 2}\) 枚举一个边的集合, 强制其连接,并有 \((-1)^{\rm popcount}\) 的容斥系数。
在这种情况下,原图会缩成若干个联通块,每个联通块填入一个相同的数字,并且去掉了 “每个数互不相同” 这个限制。
然后考虑优化这个东西,既然最后是缩成若干个联通块,我们不如直接枚举原图的联通块划分。
那么一种划分对答案的贡献就是每个联通块内(联通的每一种方案的 \((-1)^{\text{这个联通块内边数}}\) 之和)的乘积。
可以拆成这样是因为 每个联通块是独立的, \((-1)^{\rm popcount}\) 可以用线性性拆给每个联通块让他是独立的。
联通的每一种方案的 \((-1)^{\text{这个联通块内边数}}\) 之和 怎么求呢?
先考虑联通的方案怎么求。
\(f_n\) 代表 \(n\) 个点的图任意连边,联通的方案数,每次枚举一个包含最小点的联通块加进来。
减去所有图不连通的方案数,即枚举一个联通块,强制他和外界不连通,外界随便连。
在考虑这个 \(2^{\binom n 2}\) ,在 \(n\geq 2\) 时每种连奇数条边的方案和每种连偶数条边的方案数相等。
因为 \(\sum_{i\&1} \binom n i = \sum_{!(i\&1)} \binom n i\) ,所以这个东西在 \((-1)^{\text{这个联通块内边数}}\) 之和的意义下只有 \(n=1\) 时等于 \(1\), 其余情况是 \(0\)。
所以
去掉等于 \(0\) 的部分, 得到 \(f_1=1 , \ \ \ f_n =-\binom{n-1}{n-2}f_{n-1}=-(n-1)*f_{n-1}=(-1)^{n-1}*(n-1)!\)
优化一种联通块划分就很简单了,每次枚举子集加入一个联通块,钦定这个联通块包含最小的点即可。
关于钦定包含最小的点
这个操作在很久之前是困扰我很深的问题。
如果你不钦定包含最小的点,那么求出来的答案,各个联通块之间是有序的。
一种方案会被计算 \(cnt!\) 次, \(cnt\) 是这种方案内的联通块个数。
因为在当前状态删掉任意一个联通块都将统计一遍答案。
但如果你钦定了,每次就只能删掉包含最小点的联通块,那么一个方案就只会被计算一遍,适用于联通块要求无序的情况。
要考验一个计数方案是否重复计数,最好的方法就是倒过来看你的计数方法会统计一种方案几次
NOIP模拟18 C
你需要首先单步容斥,转化成求 \(n\) 个 \([1,2^n-1]\) 的数 \(XOR =0\) 的方案数。
发现这就是一个卡农,所以可以容斥dp去做。
设 \(f_n\) 代表 \(n\) 个不同的数 \(XOR = 0\) 的方案数。
即先随便选出来 \(i-1\) 个不同的数,如果他们的 \(XOR\) 不是 \(0\) ,那么你就可以添加一个数使得这 \(i\) 个数 \(XOR = 0\)
所以需要减掉他们 \(XOR= 0\) 的方案数,因为这个时候你需要加一个 \(0\),但你不能加 \(0\)。
还有一个问题就是虽然他们 \(n-1\) 个数不相同,但是最后一个数可能跟前面的数相同。
出现这种情况一定是有 \(i-2\) 个数 \(XOR=0\) ,剩下的一个在 \(2^n-1-(i-2)=2^n-i+1\) 个数里面随便选 。
还要乘上在前面的 \(i-2\) 堆选出来一堆的方案数。
于是这个题的正解结束了,下面是部分分做法
要得到这个部分分,首先你需要会 \(n\) 个 \([1,2^n-1]\) 的数可以重复 \(XOR=0\) 的方案数。
任意选 \(i-1\) 个数,用最后一个数去调整,减去最后一个数必须选 \(0\) 的方案数即可。
然后,我们只需要求出来原图划分成若干个联通块,有 \(i\) 个奇数联通块的贡献之和即可。
因为你划分成若干个联通块,只有奇数大小的联通块可以填数,偶数大小的联通块可以随便放数,对答案没有影响。
原图划分成 \(i\) 个联通块,每个联通块大小是 \(sz_i\), 那么他的贡献是 \(\prod (sz_i-1)!*(-1)^{i-1}\)
那么有一个暴力的 \(DP, dp_{i,j}\) 代表 \(i\) 个点, \(j\) 个奇数联通块的贡献之和。
这个是 \(n^3\) 的,有以下两种优化思路
- 我们记录最后有 \(j\) 个联通块的目的就是它会产生 \(f_j\) 的贡献,尝试把 \(f_j\) 写成和 \(j\) 有关的形式,用线性性拆开每次选奇数个的时候乘上他的贡献,选大小是偶数的时候乘上 \((2^n-1)\) (可以随便放数),和第一道题用的是一个套路。
那我们尝试改写 \(f_n\) ,我们将 \(-f_{n-1}\) 不断展开,可以得到柿子
一个重要的观察, \((-1)^{n-1}\) 是一个常量,因为最后奇数联通块的奇偶性之和总点数的奇偶性有关。
所以我们就是要维护这个等比数列求和,那么每次把 \(\sum_{i=0}^{lim} (1-2^n)^i \rightarrow \sum_{i=0}^{lim+1} (1-2^n)^i\) ,只需要给这个等比数列乘公比再加一,也就是记录一下答案柿子,记录一下贡献之和就可以转移。
- 优化转移,把组合数拆开,柿子变成了
对于这个柿子,奇数偶数分开做前缀和就可以转移了,记得转移偶数的时候还是用线性性拆开,每次乘上 \(2^n-1\)。
但是我这两种方法都没有想到
5.3 当时因为这个自闭了半天,其实还是不难想到的。
在问别人做法的时候,也要多加自己的思考。
NOI模拟2 C
和上一题非常类似的,如果你要打部分分,直接无脑前缀和优化求出来 \(dp\) 数组,然后 $FWT \ m $次 得到答案。
但是这题貌似还有一个类似上题正解的东东,看起来很高级。
设 \(F_i\) 代表选了 \(i\) 个不同的数的答案数组,那么把数装到桶里的数组叫 \(F_1\) , 所求的是 \(F_m\)
有转移 \(F_i = F_{i-1}*F_1-F_{i-2}*(K-1-(i-2))*(i-1)\)
乘法代表把两个数组异或卷积,由于我们计算的是有序的,最后还要除以 \(m!\)。
意义和卡农的类似吧,先选 \(i-1\) 个不重复的,再随便选一个,减去随便选的和之间不重复的 \(i-1\) 个数重复了的方案数。
NOI模拟11.5 A
这题我赛时写了一个无脑的做法,大概就是用前缀和去优化一个枚举覆盖当前点区间的暴力。
他还有一个无脑的地方,就是我在计算 \(GCD = K\) 的贡献的时候,考虑了所有 \(K\) 的倍数。
总之,我的做法是无脑+无脑=SB。
正解要对题目做最基本的转化:跨过当前点的区间个数=总共的合法区间-不跨过他的区间个数。
这步容斥是计算包含每个点贡献最基本的方法之一
求不跨过他的区间个数,最基本的想法是把每个前缀和后缀的答案求出来,然后把一个前缀和后缀的答案乘起来。
还有一个计算 \(CGD=K\) 的贡献,我们可以拿出来所有 \(GCD =K\) 的区间去计算,他的形式是(左端点,右端点区间)。
因为一个左端点出发,他的右端点只有 \(log\) 种不同的 \(GCD\) 。
容斥Dp
省选模拟14 C
这道题一入手没有什么头绪,你说要 Dp 根本不知道要记录什么状态去转移,你说要容斥,也根本找不到怎么去容斥。
不妨去尝试, \(Dp_i\) 代表前 \(i\) 个音符,有多少种悦耳的旋律。
转移? 发现一个事情,他原来没有 \(Border\) 你并不知道怎么去转移,但是你发现,如果你找到一个有 \(Border\) 的串的最小 \(Border\) ,那么他肯定是没有 \(Border\) 的,这样你就找到了子问题,即枚举最小的 \(Border\) ,所以考虑容斥 Dp。
然后大概就能通过各种多项式优化,不与讨论。