2025.9 做题记录

这里没有记录校内题单的题目,也没有记录 ARC 和 CF 比赛的题目,纯是 9 月日常训练的题目。

P5664 [CSP-S2019] Emiya 家今天的饭

睡不着开的题,结果看完题 \(3\) 分钟就秒了,更睡不着了。。。

先看三条限制,首先第一条限制随便满足,第二条限制也非常好满足,大概就是乘法原理,每个烹饪方法里面选 \(0\) 道或 \(1\) 道。第三个限制相对来说就比较烦,那我们先不管它,先看前两条限制如何满足。那么根据乘法原理,答案就是 \(\prod_{i=1}^n ((\sum_{j=1}^m a_{i,j}) + 1)-1\),后面的 \(+1\) 代表可以不选,相同类型的手法参见数的因子计数。这个可以 \(O(n)\) 计算。

下面我们来处理第三条限制,首先每道菜都小于等于 \([\frac{k}{2}]\) 这个限制太难刻画了,这个是根本限制不住的。我们来反着限制,限制 \(> [\frac{k}{2}]\)。我们这么限制之后,就变得性质非常好。第一个好在于 \(> [\frac{k}{2}]\) 相当于限制有绝对众数,这样我们假设绝对众数的个数为 \(p\),有不等式 \(p>k-p\),即 \(p-(k-p)>0\),我们也会根据这个限制进行一些操作。第二个好在于,绝对众数最多只能有一个,这样我们甚至可以直接枚举这个众数是啥。

注意到这两个优良性质之后,我们直接做完了。由 \(p-(k-p)>0\) 这个性质,我们可以直接设置一个差值动态规划。设 \(f_{i,j}\) 为考虑了前 \(i\) 种烹饪方法,目前 \(p-(k-p)=j\) 的方案数,可以知道我们最后的不合法方案就是所有 \(j>0\) 的方案数之和。由绝对众数仅存在一个,这个绝对是不重不漏的。

我们枚举那个众数 \(k\),转移也非常简单。

  1. \(f_{i,j}=f_{i-1,j}\) 代表我这一个烹饪方法一道菜都不选。
  2. \(f_{i,j}=f_{i-1,j-1}\times a_{i,k}\) 代表我这一种烹饪方法选了众数。
  3. \(f_{i,j}=f_{i-1,j+1}\times ((\sum_{j=1}^m a_{i,j}) - a_{i,k})\) 代表我这一种烹饪方法不选众数。

嗯做完了。时间复杂度 \(O(n^2m)\),可以接受。

P3214 [HNOI2011] 卡农

还是有点儿难度的,至少自己没有完全想出来。

很容易发现,这是子集族计数,那这个其实非常困难,集合的无序性导致很多东西你都想不明白,那我们不妨将其转化为数列计数,最后我们做的就是除以 \(m!\) 即可。

组合数学并没有想出很好的公式刻画它,那么我们对天然的数列性质进行动态规划。设 \(f_i\) 表示考虑前 \(i\) 个位置的合法集合数列的方案数。我们着重观察集合的性质,可以发现由集合的互异性,每个数在集合中最多出现一次。若出现 \(0\) 次则奇偶不变,否则这个数的奇偶转换。

那么对于前 \(i-1\) 个集合的集合数列,我们总能找到一个且仅能找到一个集合(包括空集),使得这 \(i\) 个集合的集合数列满足要求。具体证明可以理解为把奇偶转化为异或,然后对于每个数独立进行考虑,证完了。那么也就是说,当我们确定前 \(i-1\) 个集合后,第 \(i\) 个集合就确定了!那么在不考虑重复和空集的情况下,方案数就是 \(\binom{2^n-1}{i-1}\times (i - 1)!\)(时刻注意你是在对数列进行计数)。

那我们接下来要做的就是排除空集和重复,首先空集非常简单,因为第 \(i\) 个集合是空集,当前仅当前 \(i-1\) 个集合已经满足要求。那么减去 \(f_{i-1}\) 即可。排除重复也还可以,首先我们知道,前 \(i-1\) 个集合肯定是不重复的,那么第 \(i\) 个集合可以和前 \(i-1\) 的任意集合重复,且你把集合排成了一个数列,于是你需要选择一个位置进行重复,且你需要选择一个和其他 \(i-2\) 个集合都不重复的集合,由于重复的集合必然不会改变任何奇偶性,于是只要前 \(i-2\) 个集合合法,那么这就是一个合法的容斥方案,即减去 \(f_{i-2}\times (i-1)\times (2^n-1-(i-2))\),那么我们做完了。

注意 \(\binom{2^n-1}{i-1}\times (i - 1)!\) 前面的组合数需要暴力处理,而不能预处理阶乘和阶乘逆元处理。

集合幂级数做法:(先占着坑)

树的拓扑序计数

\(f_u\) 为以 \(u\) 为根的拓扑序个数,考虑树上动态规划,转移为

\[f_u=(\prod_{v\in son(u)} f_v)\times \binom{siz_u-1}{siz_{v_1},siz_{v_2},siz_{v_3}...,siz_{v_k}} \]

后面乘的组合数是多序列合并组合数,不会推的可以自己推推,就一步步合并就行。这是树上拓扑序计数的一般转移,我们将其拆开。变为:

\[f_u=(\prod_{v\in son(u)} f_v)\times \frac{(siz_u-1)!}{siz_{v_1}!siz_{v_2}!...siz_{v_k}!} \]

我们考虑将其变为一个通项公式而非递推形式。当然,你在知道结果后可以使用数学归纳法证明,但是我们这里讲如何想到最终这个式子的。

先考虑一下叶子的边界情况,我们有 \(f_{leaf}=1\),那么就好办了。对于 \(f_1\)(假定 \(1\) 为根),我们直接向下把所有 \(f_v\) 暴力展开,因为每个点以 \(\frac{1}{siz_{v}!}\) 作为贡献仅会被其父亲算一次,以 \((siz_u-1)!\) 作为贡献仅会被自己算一次,注意一下 \(1\) 没有父亲,所以仅会算 \((siz_u-1)!\) 的贡献。那么最终我们可以将式子化为:

\[f_{1}=(n-1)!\times \frac{\prod_{i=2}^n (siz_i-1)!}{\prod_{i=2}^n siz_i!}=\frac{(n-1)!}{\prod_{i=2}^n siz_i}=\frac{n!}{\prod_{i=1}^n siz_i} \]

至此我们把树上拓扑序计数的所有形式都展示完了。

P2606 [ZJOI2010] 排列计数

板子,注意一下,由于模数 \(p\) 可以很小,所以我们想使用 Lucas,所以别用公式的方法,直接动态规划才能使用 Lucas。

Lucas 定理

当模数 \(p\) 为质数时,\(\binom{n}{m}=\binom{[\frac{n}{p}]}{[\frac{m}{p}]}\times \binom{n \bmod p}{m \bmod p}\)。不想证,下一个。

P3244 [HNOI2015] 落忆枫音

说难也不难,说简单也不简单。反正说到底就是这种计数自己见的太少了。。。

不加边的情况:

这个非常简单,由于是 DAG,所以直接给每个点选一个父亲即可,注意不用给 \(1\) 选,连通性是天然保证的。

答案为 \(\prod_{i=2}^n ind_i\)

加边的情况:

首先是两种特殊情况。第一种是加完还是有向无环图,这种我们在后面也可以一并计算,这里不用特判。第二种是 \(t=1\) 的情况,由于 \(1\) 在原树上为根,不可能有入度,则这条边为无效边,应当直接删去。

接下来,我们的 \(ind_i\) 都代表的是加边后的 \(ind\)。首先我们考察如果还用 \(\prod_{i=2}^n ind_i\) 算会出现什么问题,显然的,图中可能会多出一个简单环。(手摸可以发现复杂环是不可能出现的,因为一个点只能由一个入度,复杂环必然导致至少一个点有两个入度)

那么我们考虑容斥,那么我们的方案要求必须有环,这个实现的方法就是强制给环上的每个点选父亲,使得其成环,其他点随意,这样一定不重不漏因为环有且仅有一个(其实等价于没有复杂环出现)。对于一个环 \(loop\),其答案为 \(\frac{\prod_{i=2}^n ind_i}{\prod_{i \space in \space loop} ind_i}\)

考虑环一定经过 \((s,t)\) 这条边,所以我们要计算的就是 \(t\)\(s\) 的路径中的答案。这个东西我们直接拓扑排序转移。设 \(f_u\)\(u\)\(t\) 的路径的答案,初值为 \(f_t=\prod_{i=2}^n ind_i\),最终我们要的是 \(f_s\)。转移为 \(f_v=\frac{\sum_{(u,v)\in E} f_u}{ind_v}\),然后我们就做完了。

没见过的话质量还是比较高的。

CF1536F Omkar and Akmar(2025.9.7 模拟赛 T3)

先写这个吧,模拟赛考的,小破结论题。结论是后手必胜。证明考虑终止状态,终止状态一定是 AB 交错,AB 中间最多只能有一个空格,那么这就导致若 \(n\neq 1\),则 AB 数量一定相等,导致后手必胜。

也就是说,后手随便作死,只要最后填满,后手就会赢。于是我们先考虑一个结束局面,最后直接乘以顺序的阶乘即可。考虑对结束局面计数。

设我们现在有 \(k\) 个棋子(\(k\) 必须是偶数),剩下有 \(n-k\) 个空格,然后我们直接把 \(n-k\) 个空格插进 \(k\) 个空里面,是 \(\binom{n-k}{k}\),但是这是个环,非常讨厌,处理不好还有可能乘个圆排列之类的,那这个是我们不想看到的。

little trick: 环可以考虑强制钦定位置 \(1\) 的状态,然后有标号的话可以强制顺时针定序计数。这在环形动态规划中较为常见。

这样我们钦定 \(1\) 为空,那么就是在把 \(n-k-1\) 个空格插在 \(k-1\) 个空隙内。钦定 \(1\) 为填数,那么就是在 \(n-k\) 个空格插在 \(k\) 个空中。最终我们的答案就是:

\[\sum_{k=1}^{[\frac{n}{2}]} (2k)!\times (\binom{2k}{n-2k}+\binom{2k-1}{n-2k-1}) \]

吗?他大部分是对的,但是有一些问题。就是你注意到,我们在钦定 \(1\) 状态并顺时针定向,所以你要钦定一下编号最小且填数的位置是 A 还是 B。所以乘以 \(2\) 即可。答案为:

\[2\times \sum_{k=1}^{[\frac{n}{2}]} (2k)!\times (\binom{2k}{n-2k}+\binom{2k-1}{n-2k-1}) \]

2025.9.7 模拟赛 T4

抄袭一下 xyh 的题解。感觉挺套路的题,但是我没见过,计数手法也只是纯难,没有什么技巧。

little trick: 对树的直径进行计数可以考虑枚举树的中心。这个中心是一个交点或者一条边需要分类讨论。

我们设 \(f_{i,j}\) 为给 \(i\) 个点分配 \(1\sim i\) 这些编号的有标号有根叶向树,且最大深度小于等于 \(j\) 的数量。设 \(g_{i,j}\) 为给 \(i\) 个点分配 \(1\sim i\) 这些编号的有标号叶向森林(把根去了),最大深度小于等于 \(j\) 的个数。(所有的根均为树的中心)

上述这两个是平凡计数手法,它可能很难但是非常经典。现在我们假设我们知道了 \(f_{i,j}\)\(g_{i,j}\) 应该怎么做。

首先这种东西肯定是中心为一条边比较好处理,因为只会把树分成两个部分。答案就是一个卷积,为 \(\sum_{k=1}^n (f_{x,k}-f_{x,k-1})\times (f_{n-x,k}-f_{n-x,k-1})\times \binom{n-1}{k-1}\)。我们重点来看一下后面的组合数 \(\binom{n-1}{k-1}\),这个代表的是,我们给左右分配编号,且编号按照原来的顺序编号(未合并前分配的 \(1\sim i\) 是新分配的编号的离散化编号),这样可以保证不重不漏。且我们要求 \(1\) 被分配在左边它本该存在的位置上。

下面说中心为一个点的情况,这个稍显麻烦,需要容斥,因为我们要保证有两个子树都有等于 \(k\) 的最大深度,我们用所有的减去只有一个的即可。即:

\[n\times((g_{n-1,k}-g_{n-1,k-1})-\sum_{x=1}^{n-1}(f_{x,k}-f_{x,k-1})\times g_{n-x-1,k-1}\times \binom{n-1}{x}) \]

注意一下式子的意义,我们先把中心挖了随后枚举根的编号,并且你要时刻注意你的根被挖了。

下面我们来求解 \(f\)\(g\),初始时 \(f_{0,0}=g_{0,0}=1\)

\(f\) 的求法非常简单,就是 \(f_{i,j}=g_{i-1,j-1}\times i\),和上面一样,随便分配根的编号。

\(g\) 的求法较为复杂,因为你是叶向森林,你需要处理一个森林之间的顺序关系,我们强制钦定我们新加入的这个子树分配到了 \(1\) 编号即可。则 \(g_{i,j}=\sum_{k=1}^i g_{i-k,j}\times f_{k,j}\times \binom{i-1}{k-1}\)

那么我们做完了。

斯特林数(Stirling 数)

第一类斯特林数 \({n\brack k}\),代表将 \(n\) 个数排列为 \(k\) 个环的方案数(数之间不同,环之间相同)。第二类斯特林数 \({n\brace k}\) 代表将 \(n\) 个数放入 \(k\) 个盒子的方案数(数之间不同,盒子之间相同)。两类斯特林数性质相似,推法也相似,但一般来说第二类斯特林数更为常用。

第一类斯特林数:

递推式:\({n\brack k}={n-1\brack k-1}+{n-1\brack k}\times (n-1)\)。在说这个递推式的意义之前,我们先说一下一种对环之间本质相同的限制的控制方法,其实就是我们可以控制环的最小值递增,这样就是对的,这种选一个代表元的方式在计数中非常常用。

那么这个递推式的意义就是要么另起一个环,要么插在前面一个数的后面(定义为顺时针),所以其实这个环是置换环(这个有助于理解后面的一个恒等式)。

第一类斯特林数与上升幂的关系:我们定义上升幂,\(x^{\overline{n}}\)\(\prod_{i=0}^{n-1} (x+i)\)。对于上升幂和普通幂,我们可以使用第一类斯特林数将它们连接起来。具体的,我们有:

\[x^{\overline{n}}=\sum_{k=1}^n {n\brack k}\times x^k \]

证明考虑组合意义,我们可以根据第一类斯特林数环的定义,我们来讲个故事。右边的意义是现在我们有 \(n\) 个不同的数组成置换环,我们先枚举置换环个数,然后计算这些无序置换环组成的方法,最后给每个置换环染上 \(1\)\(x\) 种任意一种颜色的方案数。那么看好,左边也是同样的意思,和我们第一类斯特林数的递推式相似,加入一个新的有标号点,我们可以成立一个新环,染上 \(1\)\(x\) 的任意一种颜色,也可以插到前面的一个数后面(顺时针)并跟随前面的数的颜色,这样插入第 \(i\) 个数就有 \(x+i-1\) 种选法。容易知道左右边的组合意义等价,于是两者相等。

注意我们有时候可以强制把上升幂拆成后面那种形式方便求和换序。(Tip:上升幂本身是由组合表示方法的,就是一个组合数乘以一个阶乘,这很简单)

第一类斯特林数与下降幂的关系:我们定义下降幂,\(x^{\underline{n}}\)\(\prod_{i=0}^{n-1} (x-i)\)。我们有:

\[x^{\underline{n}}=\sum_{k=1}^n (-1)^{n-k}\times {n\brack k}\times x^k \]

这个东西其实就是你展开一下,跟上面那个上升幂对比一下系数就可以了。同时注意,这也是有符号斯特林数的定义。

另一些可能有用的东西:\({n\brack 1}=(n-1)!\),这个就是圆排列。还有就是 \(n!=\sum_{k=0}^n {n\brack k}\),这个证明依然可以考虑组合意义,左边是排列数,我们知道排列一定可以写成一个置换环的集合,所以右边就是枚举置换环的数量,并进行累加,两者组合意义显然相等。

第二类斯特林数:

递推式:\({n\brace k}={n-1\brace k-1}+{n-1\brace k}\times k\)

与第一类斯特林数相似,这个就更为简单,要么自己另起一个盒子,要么插入之前的一个盒子。可以发现,第二类和第一类这种插入方法天然保证了代表元递增,符合我们的控制方法。

第二类斯特林数与下降幂的关系: 这个非常重要,是普通幂转下降幂的公式。

\[x^n=\sum_{k=0}^n {n\brace k}\times x^{\underline{k}} \]

证明考虑组合意义:左边是给 \(n\) 个有标号染 \(1\)\(x\) 的任意颜色。右边是先枚举盒子个数,把 \(1\)\(n\) 分为 \(k\) 个集合,然后依次染成不同的颜色(对盒子染色)。两者组合意义显然等价,于是证毕。

第二类斯特林数的通项公式:这个所谓的通项公式是线性的,也就是用容斥实现的通项公式。不是很优美,但也能凑合看()具体做法就是我们直接把限制全部打开,盒子没有顺序我们就强制规定其有顺序最后除以 \(k!\),不能有空盒子,我们就看他能有空盒子然后大力容斥(由于是定序容斥所以带二项式系数)。具体的,我们有:

\[{n\brace k} =\frac{1}{k!} \sum_{i=0}^k (-1)^i \times \binom{k}{i} \times (k-i)^n \]

嗯这个手法上还是比较常规的。

简单应用:自然数幂和

自然数幂和一般表示为一个二元函数:\(f(n,k)=\sum_{i=1}^n i^k\)。这个一般算起来是 \(O(n\log k)\) 的,非常不优,而第二类斯特林数所代表的斯特林反演可以将其转化为只与 \(k\) 相关,而与 \(n\) 无关的复杂度做这个式子。

我们进行如下变换:\(f(n,k)=\sum_{i=1}^n i^k=\sum_{i=1}^n \sum_{j=0}^k {k\brace j}\times i^{\underline{j}}=\sum_{i=1}^n \sum_{j=0}^k {k\brace j}\times j!\times \binom{i}{j}\)

接下来我们进行关键的求和换序,注意到 \({k\brace j}\times j!\) 都与 \(i\) 无关,于是我们把 \(j\) 的枚举提到前面,变为 \(\sum_{j=0}^k {k\brace j}\times j! \times (\sum_{i=j}^n \binom{i}{j})\)

然后需要用到一个非常重要的组合恒等式,\(\sum_{i=j}^n \binom{i}{j}=\binom{n+1}{j+1}\),这个可以归纳证明。

然后这个就变成仅枚举 \(k\) 的式子了,最终的式子为:\(\sum_{j=0}^k {k\brace j}\times j! \times \binom{n+1}{j+1}\)。这个东西可以做到 \(O(k\log k)\),那么基本斯特林数就介绍到这里了。

CF1342E Placing Rooks

算是斯特林数入门题了,首先我们发现,你只要能覆盖到全部棋盘,就必须每行都有一个或者每列都有一个,所以最后你算出那个答案得乘以 \(2\),除了 \(k=0\),因为这种是全错开的,两种一样。

考虑 \(k\) 的上界,显然 \(k\leq n-1\),你考虑把所有东西放在一列里必然是最优的。那么如果你把所有的分摊到两列中,那么答案就是 \(n-2\)。所以 \(k\) 个互相攻击其实等价于把这些东西分配到 \(n-k\) 列里。我们把列看作有标号的盒子,而棋子赋予当前行号为标号。

问题就转化为了有标号的 \(n\) 个球放置到 \(n-k\) 个有标号的盒子里且不能有空盒的方案数。这个和第二类斯特林是区别在于盒子本质不同,但是盒子本质不同肯定是好处理的,直接乘以 \((n-k)!\) 即可,然后你还要选 \(n-k\) 列,于是再乘以 \(\binom{n}{n-k}\) 即可。

那么最终答案就是:

\[(1+[k\neq 0])\times {n \brace n-k}\times (n-k)!\times \binom{n}{n-k} \]

第二类斯特林数用通项公式容斥计算即可。

P5204 [USACO19JAN] Train Tracking 2 P

《Min Limited Sequence》

考虑直接加强问题把限制改成任意的长度限制,把题目转化为经典黑题 Max Limited Sequence。

发现一个点能且仅能满足一个限制,所以每个限制的计数是独立的。

直接全拆了最后乘在一起即可。设 \(f_i\) 为最后一个满足限制的点为 \(i\)(离散化后的)的方案数。那么转移方程显然为 \(f_i=f_j\times x^{i-j-1}\),不存在什么线段树优化整体 dp 什么的。

P6348 [PA 2011] Journeys

线段树优化建图板子,建一棵入线段树建一棵出线段树。注意到一个区间向一个区间连边可以拆为一个区间向一个虚点连边并由这个虚点向一个区间连边,并且一个点向一个区间连边的过程中,区间可以在线段树上被拆为 \(\log\) 个。

线段树上再按序连上边即可,这样就和原图等价了。

posted @ 2025-08-29 17:51  DataEraserQ  阅读(18)  评论(0)    收藏  举报