计数合集
Problem A. CF1096E The Top Scorer
题意:
小明在打比赛,包括小明自己一共有 \(p\) 名选手参赛,小明是第一个人,每个人的得分是一个非负整数。最后的冠军是得分最高的人,如果得分最高的人有多个,就等概率从这些人中选一个当冠军。
现在小明已知了自己的得分大于等于 \(r\),所有选手的得分和为 \(s\)。求小明成为冠军的概率,结果对 \(998244353\) 取模。
\(s,r \leq 5000\),\(p \leq 100\)。
解法:
有一个复杂度很厉害的做法,不过范围比较小,考虑一个暴力做法。
先算总方案数,可以直接插板。
然后先枚举小明的分数 \(r \leq x \leq s\),然后枚举有多少个最大值,即有多少人和小明同分。这样问题变成了对于剩下的人,计数每个人得分不超过某个值,且和为某个值的方案数。这是一个很经典的容斥。枚举有多少人不合法,然后插板即可。总复杂度 \(O(sp^2)\),可以通过。
Problem B. CF1773G Game of Questions
题意:
Genie 正在参加一个问答比赛。比赛共 \(n\) 题,有 \(m\) 个参赛者(Genie 为 \(1\) 号参赛者)。
比赛的形式如下:先将 \(n\) 道题随机排序(即每个排列出现的概率都是 \(\dfrac{1}{n!}\)),然后按排列的顺序会依次问出这 \(n\) 个问题。问一个问题时,若所有人都会或所有人都不会则无事发生,否则不会的人会被淘汰。在 \(n\) 个问题都被问完之后,未被淘汰的人就都赢得胜利。
现在给出每个人是否会每道题,请求出 Genie 获胜的概率。使用浮点数输出。
\(n \leq 2 \times 10^5\),\(2 \leq m \leq 17\)。
时间限制 \(5\) 秒,空间限制 \(1\) GB。
解法:
好厉害的题。
直接考虑什么样的排列是很难的,虽然确实可以推出一些性质,但并不能对计算概率起到很大帮助。
但是不考虑对排列计数,而是直接算概率呢?这题中有一个很好的性质,即如果某道题对于目前在场玩家不能淘汰任何一个人,或者淘汰了所有玩家,那么这道题在今后的顺序不影响概率,原因是无论放在哪里都一样。
现在考虑一个 DP,记 \(f_S\) 表示目前存活的人为集合 \(S\) 时,Genie 获胜的概率。考虑所有题目,如果某个题目不影响存活集合或者这个集合的人都不会即可则忽略。如果此时所有题目都被忽略了,则这是一个终止态,累加答案。否则,此时必然不是一个终止态,可以选择某个题目转移到 \(S\) 的某个子集 \(T\),转移形式为 \(\dfrac{1}{c} f_S \rightarrow f_T\),其中 \(c\) 是本质有意义的题目集合。如果直接枚举 \(T\),则这是一个子集枚举的过程,复杂度为 \(O(3^m)\),但是问题转化成了问有多少个题目集合可以使存活集合从 \(S\) 变为 \(T\)。考虑预处理 DP 值 \(g_{S,T}\),表示有多少题目集合能从 \(S\) 到 \(T\)。这个东西是可以递推的。进一步来说对于 \(S\) 为全集先预处理,对于 \(S\) 不为全集,考虑某一个不在 \(S\) 内的数 \(x\)。发现转移只有两种,即 \(g_{S \bigcup \{x\},T}\) 与 \(g_{S\bigcup \{x\}, T\bigcup \{x\}}\),且这两部分没有重复的,直接累加即可。由于这里的 \(T\) 也是 \(S\) 的子集,所以复杂度还是 \(O(3^m)\)。
这样我们应该已经做到了正确复杂度了,不过空间也是 \(O(3^m)\) 的,为了对 \(T\) 进行编号复杂度可能变为 \(O(nm+3^mm)\),仍然可以通过。精细实现能将 \(m\) 删去。
这个题启发我们对概率的一些思考方式。如果某些东西不会影响概率,则忽略他们。
Problem C. CF1909F2 Small Permutation Problem (Hard Version)
题意:
给定长度为 \(n\) 的序列 \(a\),且满足 \(a_i \in [-1, n] (1 \le i \le n)\)。
一个长度为 \(n\) 的排列 \(p\) 被称为好排列,当且仅当:
- 对于任意 \(1 \le i \le n\),如果 \(a_i \ne -1\),则 \(\sum_{j=1}^i [p_j \le i] = a_i\)。
求有多少个这样的好序列,模 \(998244353\)。
多组数据。数据范围:\(1 \le T \le 10^4, \sum n \le 2 \times 10^5\)。
解法:
让我们先考虑 F1,即 \(a_i \neq -1\)。
先判掉一些显然的无解,比如 \(a_n \neq n\) 或 \(a_i > i\)。同时容易注意到 \(a_i \leq a_{i-1}+2\) 恒成立。
假设 \(a_0=0\)。
直接对排列计数有点难以下手。但是对于排列来说有一个经典套路,我们可以将一个长度为 \(n\) 的排列对应到一个 \(n \times n\) 的黑白网格上,将 \((i,p_i)\) 的格子染黑,所有黑格子都是不同行不同列的。仔细思考一下发现这个转化是很优美的,因为对于排列限制可以转为格 \((i,i)\) 左下角有 \(a_i\) 个黑格。于是我们可以考虑递推。从 \(i\) 到 \(i+1\) 的过程,填入某些黑格。发现新增的是一个横着加竖着的轮廓。此时可以分类讨论:
- 若 \(a_i = a_{i-1}\),那么我们不应该在新的轮廓中填入任何黑格。
- 若 \(a_i = a_{i-1}+1\),应该在新的轮廓中填入恰好一个黑格,但这个黑格并不是所有地方都合法。具体来说在第 \(i\) 列填,则有 \(a_{i-1}\) 个不合法,合法的共 \(i-a_{i-1}\) 个。横着的除了最后一个位置外,有 \(i-1\) 个,但有 \(a_{i-1}\) 个位置已经被填掉了,所以是 \(i-a_{i-1}+i-1-a_{i-1}=2(i-a_{i-1})-1\) 个合法位置。将答案乘上这个系数就行。
- 若 \(a_i=a_{i-1}+2\),类似第二类的可以推出贡献系数为 \((i-1-a_{i-1})^2\)。
至此,我们在线性复杂度内解决了 F1。Submission Link.
那 F2 不就迎刃而解了吗?考虑所有不为 \(-1\) 的位置,把相邻的拉出来依次算,贡献系数是若干排列组合数乘在一起,可以简单推出。所以我们也在线性复杂度内解决了 F2。
Problem D. CF1487G String Counting
题意:
你有 \(26\) 个不同的字符,第 \(i\) 个字符有 \(c_i\) 个(\(\frac{n}{3} < c_i \leq n\))。
你希望用这些字符,构造出一个长度为 \(n\) 的字符串(每个字符在字符串中出现的个数不超过 \(c_i\)),使得这个字符串上不存在长度为奇数且大于 \(1\) 的回文串。求出方案数对 \(998244353\) 取模的结果。
\(3 \leq n \leq 400\),时限 \(10\) 秒。
解法:
无脑题。
注意到不存在长度为奇数且大于 \(1\) 的回文串,等价于不存在长度为 \(3\) 的回文串。
\(c_i > \dfrac{n}{3}\) 很有意思啊。容易发现至多只有两种字符数量超限。又容易知道这两种字符是什么其实不重要,所以直接做 DP,记 \(f_{i,j,k,x,y}\) 表示前 \(i\) 个字符,最后两个是 \(j\) 和 \(k\),且目标的那两个字符出现次数为 \(x\) 和 \(y\)。发现其中对于 \(j,k\) 来说存在大量偏序与限制,状态数远小于 \(n^3\),所以虽然总复杂度为 \(O(n^3\left| \Sigma \right|^2)\),但完全跑不满,可以通过。没有经过代码实现,感觉写起来很大便,跳了。
Problem E. CF1295F Good Contest
题意:
给定 \(n\)。
\(a_i\) 是在 \([l_i, r_i]\) 上均匀随机分布的整数,求 \(a_{1 \dots n}\) 单调不增的概率,对 \(998244353\) 取模。
\(2 \leq n \leq 50\),\(0 \leq l_i \leq r_i \leq 998244351\)。
解法:
考虑对区间离散化,显然所有值域内的整数被分为了若干段,可以考虑进行 DP,记 \(f_{i,j}\) 为前 \(i\) 个数,最后这个数在离散化后的第 \(j\) 段的答案。转移考虑这个数之前有多少个数是同一段的,那么对于那个不同段的直接用直接 DP 值,然后乘以一个形如 \(x\) 个数,每个数在 \([1,k]\) 中,单调不增的方案数。这个是一个组合数可以直接算。直接做是四次方的,可以通过优化组合数的递推做到三次方。
Problem F. CF1237E Balanced Binary Search Trees
题意:
给定 \(n\),计算有多少棵 \(n\) 个点的二叉搜索树满足:
- 树上每个点写着一个权值,权值互不相同且构成 \(1\sim n\) 的排列。
- 所有点到根的距离之和最小。
- 点 \(u\) 如果有左儿子 \(v\),那么 \(u\) 和 \(v\) 的点权奇偶性不同;点 \(u\) 如果有右儿子 \(w\),那么 \(u\) 和 \(w\) 的点权奇偶性相同。
答案对 \(998244353\) 取模。
\(1 \le n \le 10^6\)。\(3\) 秒,\(512\) MB。
解法:
考虑一个什么样的二叉搜索树是合法的。条件二显然等价于上面若干层全都填满,最后一层中选了若干个。条件 \(1\) 不需要考虑,只要树的结构确定则点权必然唯一确定。条件 \(3\) 是我们唯一需要考虑的。事实上我们对于每个点 \(u\),对于其左儿子和右儿子,在树的中序遍历上考虑,这样可以得到形如 \(u\) 左儿子或右儿子的左或右儿子子树大小为奇数或偶数的一些条件。注意到这是一个完全二叉树,直接做背包的话次数是对的。但是背包是卷积形式,上个 NTT 就做完了。
Problem G. CF1743G Antifibonacci Cut
题意:
定义 \(01\) 串 \(f\) 为斐波那契串,其中 \(f_1=0,f_2 = 1,f_{n}=f_{n-1}+f_{n-2}\),其中 \(+\) 代表拼接。再定义 \(g(s)\) 表示把 \(s\) 分割成若干个子串,并且没有任何子串是斐波那契串的方案数。现给出 \(n(n\leq 3000)\) 个 \(01\) 串 \(s_1,s_2,...,s_n\)(\(\left| s_i\right|\leq 1000\)),要求对于每个 \(i\),计算 \(g(s_1+s_2+...+s_i)\pmod {998244353}\)。空间限制为 \(4\) MB,时间限制为 \(12\) 秒。
解法:
令 \(m=\sum \left| s_i \right|\),\(F\) 为斐波那契串集合。
如果忽略空间限制那还是很好做的。考虑 DP,记 \(f_i\) 表示前 \(i\) 个字符的答案。转移枚举最后一段 \([j,i]\),当 \(s[j,i] \notin F\) 时有 \(f_{j-1} \to f_i\),复杂度 \(O(m^2)\)。注意到长度不超过 \(m\) 的斐波那契串只有 \(O(\log m)\) 个,枚举他们并用哈希判断即可做到 \(O(m \log m)\),空间为 \(O(m)\),无法通过。
考虑空间复杂度瓶颈。我们要记录所有位置的 DP 值,但事实上只有那些 \(s[j,i] \in F\) 的 \(j\) 才有意义。考虑存下所有可能有用的 \(j\),即可能有 \(s[j,i]\in F\),换句话来说 \(s[j,i]\) 是某个斐波那契串前缀。可以通过 Border 分析出这样的 \(j\) 不会很多。每次将哈希值往后加,同时需要判断某个哈希值是否为斐波那契串前缀。对于求某个斐波那契串前缀,考虑将其拆为两部分,一部分是一个完整的,另一部分是另一个斐波那契串前缀。这样不需要预处理斐波那契串前缀哈希值,于是可以做到 \(O(\log m)\) 空间。
Problem H. P10614 BZOJ3864 Hero meet devil
题意:
给定一个字符集为 ACGT
的字符串 \(S\)。定义 \(\text{LCS}(S,T)\) 为两个字符串 \(S,T\) 的最长公共子序列。
对于每个 \(0\leq i \leq |S|\),求有多少个长度为 \(m\),字符集 ACGT
的字符串 \(T\),满足 \(|\text{LCS}(S,T)|=i\),答案对 \(10^9+7\) 取模。
多测,\(t\) 为测试组数,\(1\leq t \leq 5\),\(1\leq |S| \leq 15\),\(1\leq m\leq 1000\)。
解法:
令 \(n = \left| S \right|\)。
DP 套 DP 模板。
对于最长公共子序列,一般做法是进行 DP,记 \(f_{i,j}\) 表示 \(S\) 前 \(i\) 个和 \(T\) 前 \(j\) 个 LCS。转移显然。
考虑 DP 套 DP,记 \(f_{i,j}\) 表示考虑了 \(T\) 的前 \(i\) 个字符,目前 \({f_{1,i},f_{1,i},\cdots,f_{n,i}}\) 为状态 \(j\)。\(j\) 显然有 \(n^n\) 种,无法通过。注意到 \(f_{x,i} - f_{x-1,i} \in [0,1]\),于是只记录 \(j\) 的差分数组即可。预处理所有内层转移边,复杂度 \(O(m2^n\left|\Sigma\right|)\)。
Problem I. CF1118F2 Tree Cutting (Hard Version)
题意:
给定一个有 \(n\) 个节点的树,结点可能有颜色,共 \(k\) 种颜色,颜色编号为 \(1\) 到 \(k\),保证每种颜色都出现过。有的点没有颜色,用 \(0\) 表示。在树上删去 \(k-1\) 条边,即划分成 \(k\) 个联通块,使每个联通块中恰好含一种颜色,颜色为 \(0\) 的节点可以在任意联通块中。求划分的方案数,对 \(998244353\) 取模。
\(2 \leq k \leq n \leq 3 \times 10^5\),\(2\) 秒。
解法:
考虑删去边数很奇怪。容易发现最终每种颜色都在同一个连通块中。所以原树上同颜色的点必然构成连通块(忽略无颜色的点)。所以无解是容易判断的,对每种颜色建立虚树暴力跳即可。这样问题变为了一棵新树,每个点可能有颜色,删去若干条边,使得每个连通块恰有一个有颜色的点。这个容易 DP,记 \(f_{i,0/1}\) 即可,总复杂度 \(O(n \log n)\),瓶颈在于求 LCA。线性 LCA 或直接树上并查集可以做到线性。
Problem J. P5395 第二类斯特林数·行
题意:
给定 \(n\),求 \(\begin{Bmatrix} n \\0 \end{Bmatrix},\begin{Bmatrix} n \\1 \end{Bmatrix},\cdots, \begin{Bmatrix} n \\n \end{Bmatrix}\)。答案对质数 \(167772161=2^{25}\times 5+1\) 取模。
\(1 \leq n \leq 2 \times 10^5\)。
解法:
考虑第二类斯特林数的容斥公式。枚举有多少钦定为空的集合可得 \(\begin{Bmatrix} n \\m \end{Bmatrix}=\dfrac{1}{m!}\sum \limits_{i=0}^m (-1)^{i} \times \dbinom{m}{i} \times (m-i)^n\)。
将 \(\dbinom{m}{i}=\dfrac{m!}{i!(m-i)!}\) 拆开,\(m!\) 被抵消。不然发现 \(h(x)=\begin{Bmatrix} n \\m \end{Bmatrix}\) 等于 \(f(x)=(-1)^x \times \dfrac{1}{x!}\) 与 \(g(x)=x^n \times \dfrac{1}{x!}\) 的卷积。模数是一个 NTT 模数,直接 NTT 即可。
Problem K. CF2030G1 The Destruction of the Universe (Easy Version)
题意:
对于一个正整数区间集合 \(S=\{[l_1,r_1],[l_2,r_2],\cdots,[l_n,r_n]\}\),定义其分数为最小的操作次数,使得这些区间交集非空。每次操作如下:
选择 \(1 \leq i \leq k\),令 \([l_i,r_i]\) 变为 \([l_i-1,r_i]\) 或 \([l_i,r_i+1]\)。
给定集合 \(S\),求其所有子集的分数之和,对 \(998244353\) 取模的结果。
\(1 \leq n \leq 5000\),\(1 \leq l_i \leq r_i \leq n\)。
解法:
肯定先考虑一个集合的分数怎么计算。直接做就是枚举最终交点位置,计算次数然后取最小值,但这个式子有最小值,不容易计算。考虑贪心。对于集合 \(S\),定义 \(score(S)\) 表示其分数。选出 \(l\) 最大的 \(i\) 和 \(r\) 最小的 \(j\)。若 \(l_i \leq r_j\),则 \(score(S)=0\),否则 \(score(S)=l_i-r_j+score(S\setminus \{[l_i,r_i],[l_j,r_j]\})\)。证明考虑归纳,左式大于等于右式显然成立。且按照这样做确实能取等。
现在考虑枚举两个区间 \([l_i,r_i]\) 和 \([l_j,r_j]\),如果他们有交,则不会产生贡献。否则,不妨假设 \(r_i < l_j\),则贡献为 \(l_j-r_i\) 乘上一个贡献系数。发现这两个区间会被选择,当且仅当所有 \(l\) 大于 \(l_j\) 的区间数量与 \(r<r_i\) 的区间数量相同。令 \(x\) 为 \(l>l_j\) 区间数量,\(y\) 为 \(r<r_i\) 区间数量。则贡献系数形如 \(\sum \limits_{i} \dbinom{x}{i}\dbinom{y}{i}2^{n-2-x-y}\)。注意到 \(\dbinom{x}{i}\dbinom{y}{i}\) 是范德蒙德卷积形式,最终可以直接变成一个组合数。这样得到了 \(O(n^2)\) 的复杂度。
Problem L. P6078 [CEOI2004] Sweets
题意:
给定 \(n,a,b,m_i\),有 \(n\) 种物品,每种有 \(m_i\) 个,你需要在每种物品中选若干个,使得物品总数在 \([a,b]\) 之间,求方案数对 \(2004\) 取模的结果。
\(1 \leq n \leq 10\),\(0 \leq a \leq b \leq 10^7\),\(0 \leq m_i \leq 10^6\)。时限 \(100\) 毫秒。
解法:
生成函数入门题。
对选的数刻画 OGF,不难发现对于每种物品选择的 OGF 应该为 \(\sum \limits_{j=0}^{m_i} x^j=\dfrac{1-x^{m_i+1}}{1-x}\)。则所有选法的 OGF 为 \(\prod \limits_{i=1}^n \dfrac{1-x^{m_i+1}}{1-x}={(1-x)^{-n}}\prod \limits_{i=1}^n (1-x^{m_i+1})\)。答案则为 \(\sum \limits_{j=a}^b [x^j]({(1-x)^{-n}}\prod \limits_{i=1}^n (1-x^{m_i+1}))\)。对于后面的 \(n\) 项乘积,可以直接暴力展开,复杂度 \(O(2^n)\)。对于前面的 \((1-x)^{-n}\),考虑使用广义二项式定理展开,则有 \((1-x)^{-n}=\sum \limits_{i} (-x)^i \dbinom{-n}{i}\),将广义组合数 \(\dbinom{-n}{i}\) 展开,得 \((-x)^i\dbinom{-n}{i}=x^i\dbinom{n+i-1}{i}\)。现在考虑对于后面 \(n\) 项乘积得到的每个 \(c_kx^k\),贡献为 \(c_k \times \sum \limits_{i=a-k}^{b-k} [x^i]((1-x)^{-n}) = \sum \limits_{i=a-k}^{b-k} \dbinom{n+i-1}{i}\)。差分一下变为 \(\sum \limits_{i=0}^{b-k} \dbinom{n+i-1}{i}-\sum \limits_{i=0}^{a-k-1} \dbinom{n+i-1}{i}\)。由于 \(\dbinom{n+i-1}{i}=\dbinom{n+i-1}{i-1}\),所以前者等于 \(\dbinom{n+b-k}{n}\),后者等于 \(\dbinom{n+a-1-k}{n}\)。直接计算即可。
但是你先别急,模数不是质数,虽然 \(\dbinom{n+b-k}{n}\) 看似可以直接用 \(\dfrac{(n+b-k)^{\underline{n}}}{n!}\) 在 \(O(n)\) 复杂度内计算,但是并不能计算 \(n!\) 的逆元。这里要引入一个 Trick,注意到 \(n \leq 10\),所以 \(n!\) 很小,我们在计算时将分子的结果对 \(n! \times 2004\) 取模,最后将答案除以 \(n!\) 即可,这里的除是直接整除,不需要逆元,接下来我们来说明这样做的正确性:
令 \(x= (n+b-k)^{\underline{n}}\),记 \(r \equiv \dfrac{x}{n!}\pmod {2004}\),即 \(r\) 为我们需要的答案。考虑 \(\dfrac{x}{n!}=2004k+r\),则 \(x=2004kn!+rn!\),有 \(x \equiv rn! \pmod {2004 \times n!}\)。又 \(r < 2004\),则 \(x \bmod (2004 \times n!) = rn!\),所以 \(r = \dfrac{x \bmod (2004 \times n!)}{n!}\)。
这样我们在 \(O(2^nn)\) 的时间复杂度内解决了本题。
Problem M. P4841 [集训队作业2013] 城市规划
题意:
给定 \(n\),求 \(n\) 个点有标号简单无向连通图个数,答案对质数 \(1004535809 = 479 \times 2 ^{21} + 1\) 取模。
\(n \leq 1.3 \times 10^5\),时限 \(2\) 秒。
解法:
设 \(f_n\) 表示所求答案,\(g_n\) 表示 \(n\) 个点有标号无向图个数,不要求连通。显然有 \(g_n = 2^{\binom{n}{2}}\)。
另一方面,考虑 \(1\) 号点所在连通块大小,则有 \(g_n = \sum \limits_{i=1}^n \dbinom{n-1}{i-1}f_ig_{n-i}\),得到 \(f_n\) 递推公式 \(f_n = g_n - \sum \limits_{i=1}^{n-1} \dbinom{n-1}{i-1}f_ig_{n-i}\)。直接做复杂度为 \(O(n^2)\)。
进一步,注意到 \(f_n\) 形如自卷积,将组合数拆开后分治 NTT 即可做到 \(O(n \log^ 2n)\)。
Problem N. Public NOIP Round7 T2 排列计数
题意:
给定一个长度为 \(n\) 的两两不同的整数序列 \(a_1,a_2,\cdots,a_n\) 和正整数 \(k\),求有多少 \(1\) 到 \(n\) 的排列 \(p\),满足 \(\forall 1 \leq i < n,\left| a_{p_i} - a_{p_{i+1}}\right| \neq k\),答案对 \(998244353\) 取模。
\(1 \leq n \leq 5000\),\(1 \leq k \leq 10^6\),\(1 \leq a_i \leq 10^9\)。
解法:
好题啊。
考虑一个弱化版。若对于所有 \(1 \leq i < n\) 都有 \(a_{i+1}-a_i = k\) 怎么做?这里可以考虑一个朴素 DP,记 \(f_{i,j}\) 表示已经插入了 \(a_1,a_2,\cdots,a_i\),且目前有 \(j\) 个位置符合 \(\left| a_{p_i}-a_{p_{i+1}} \right| = k\),但是你发现这样没法转移,因为你不知道 \(a_i - k\) 和 \(a_i - 2k\) 是不是相邻的。于是在状态上加入 \(0/1\),记 \(f_{i,j,0/1}\) 表示之前的状态,但是 \(0/1\) 表示 \(a_i\) 是否与 \(a_{i}-k\) 相邻的方案数。这样可以简单地分析新增 \(a_{i+1}\) 的插入方式进行转移,复杂度 \(O(n^2)\)。
这启发我们将原序列排序后分为若干子序列,每个子序列相邻两个数差为 \(k\)。他们内部的方案数可以通过预处理上述 DP 求出,但问题在于合并。对于两个排列合并,完全无法求出新的差为 \(k\) 的数量。
那难道这个做法就做不了了吗?并非。对于这个问题,我们希望求出相邻差为 \(k\) 数量恰好为 \(0\) 的排列个数。但同时由于合并与插入时数量可能增加或减少,于是我们应该要对于每个 \(i\) 求出相邻差为 \(k\) 数量恰好为 \(i\) 的排列个数。但是你看到恰好,考虑二项式反演变成钦定!对于上述的 DP,只需要在 DP 后面对结果做一个一般的反着的二项式反演就行,然后你惊喜地发现现在排列合并只是一个卷积形式,同时乘上一个形如 \(\dbinom{a+b}{a}\) 的组合数贡献。范围很小暴力卷积就行,最后二项式反演回去就对了!复杂度还是 \(O(n^2)\)。
Problem O. CF2025E Card Game
题意:
在伯兰最受欢迎的卡牌游戏中,使用的是一个 $ n \times m $ 的卡牌组。每张卡牌都有两个参数:花色和等级。游戏中的花色编号从 $ 1 $ 到 $ n $,等级编号从 $ 1 $ 到 $ m $。每种花色和等级的组合中恰好有一张卡牌。
一张花色为 $ a $、等级为 $ b $ 的卡牌可以打败一张花色为 $ c $、等级为 $ d $ 的卡牌的条件有两个:
- $ a = 1 $ 且 $ c \ne 1 $ (花色为 $ 1 $ 的卡牌可以打败任何其他花色的卡牌);
- $ a = c $ 且 $ b > d $ (同一花色的卡牌可以打败等级较低的卡牌)。
两名玩家进行游戏。在游戏开始之前,他们各自获得正好一半的牌组。第一名玩家获胜的条件是,对于第二名玩家的每一张卡牌,他都能选择一张可以打败它的卡牌,并且没有卡牌被选择两次(即存在一组匹配,第一名玩家的卡牌与第二名玩家的卡牌相匹配,每对中的第一名玩家的卡牌打败第二名玩家的卡牌)。否则,第二名玩家获胜。
你的任务是计算出将卡牌分配的方式,以便第一名玩家获胜的方式数量。两种方式被认为是不同的,如果存在一张卡牌在一种方式中属于第一名玩家,而在另一种方式中属于第二名玩家。结果可能非常大,因此请输出结果对 $ 998244353 $ 取模。
\(1 \leq n, m \leq 500\)。
解法:
事实上整个过程类似括号匹配。不妨令第一名玩家获得的卡牌为右括号,第二名获得的为左括号。则可以发现第一行的左括号必须总能找到右括号匹配,同时可能剩下若干没匹配的右括号,这些右括号可以给第 \(2\) 到 \(n\) 行中多出来的未匹配左括号进行匹配。
考虑 DP,记 \(f_{i,j,k}\) 表示长度为 \(i\) 的括号序列,目前有 \(j\) 个左括号失配,还剩 \(k\) 个右括号可以对前面匹配的方案数。这个 DP 可以朴素转移,然后对 \(n-1\) 行做卷积,最后枚举第一行剩的右括号数量即可。复杂度 \(O(n^3)\)。
Problem P. 云斗学院 2024 S 赛前模拟 T2 步行回家
题意:
有 \(n\) 个点,标号为 \(1\) 到 \(n\),你现在位于 \(n\) 号点,若你现在在点 \(x\),你可以选择:
- 若 \(x > 1\),走到 \(x-1\)。
- 若 \(x<n\),走到 \(x+1\)。
- 选择正整数 \(d \mid n\),走到 \(d\)。
你不能到达某个位置多次,你也不能连续三次选择的操作种类依次为 \(1\),\(3\),\(1\)。问有多少种从 \(n\) 走到 \(1\) 的路径,两条路径不同当且仅当路径某个位置不同或某次选择的操作种类不同。答案对 \(998244353\) 取模。
\(1 \leq n \leq 10^5\),时限 \(1\) 秒。
解法:
考虑整个移动过程,其实可以将其按照操作 \(3\) 分段,段与段之间只能前后移动。于是考虑记一个 DP,\(f_{i,j}\) 表示最后一步操作是从 \(i\) 的倍数 \(j\) 走过来的方案数,但是这样不能处理连续三次操作的限制。于是多记一个 \(0/1\),表示最后两步操作是否为 \(13\)。直接转移需要枚举 \((i,j)\) 之间的数,复杂度大概为 \(O(n^2 \ln n)\),无法通过。注意到其实可以整除分块,但是还是带个 \(\ln\) 之类的,还是太菜了。但是如果我们倒着转移,从 \(f_{i,j,0/1}\) 转移到 \(f_{k,i,0/1}\),其中 \(k \mid i\),那么在计算所谓的 \((i,j)\) 之间的数时,我们并不要求起点 \(>j\),因为我们是倒着转移的。这样我们维护单点修改区间求和就能通过本题了。
Problem O. [ABC313Ex] Group Photo
题意:
存在 \(2 \times n + 1\) 个人需排队照相, 分为两排。
第一排的人高度分别为:\(a_1, a_2, a_3, ... , a_n\)。
第二排的人高度分别为:\(b_1, b_2, b_3, ... , b_n, b_{n+1}\)。
你可以自行决定这些人的排列顺序, 使其符合如下条件 :
- \(b_1 > a_1\)
- \(b_{n + 1} > a_n\)
- \(b_{i} > \min(a_i, a_{i - 1}) \text{ }( 2 \le i \le n)\)
请问存在合法的第一排排列方案有多少?答案对 \(998244353\) 取模。
\(1 \leq n \leq 5000\),\(1 \leq a_i, b_i \leq 10^9\),所有 \(a,b\) 两两不同。
解法:
设 \(a_0=a_{n+1}=+\infty\),若确定了 \(a\) 的排列,判定合法非常容易。对所有 \(\min(a_i,a_{i-1})\) 与 \(b\) 排序后逐位比对就行了。
这启发我们将 \(a\) 从大到小进行插入。
考虑连续段 DP,记 \(f_{i,j}\) 表示插入了 \(a\) 中前 \(i\) 大的数,目前形成了 \(j\) 个连续段的方案数。转移考虑要么新开连续段,要么插在某个连续段首尾,或者插在两段中间并合并。每种转移都可以 \(O(1)\) 计算,复杂度 \(O(n^2)\)。
Problem P. P11256 [GDKOI2023 普及组] 置换
题意:
给定 \(n,k\) 和长度为 \(n\) 的排列 \(p_1,p_2,\cdots,p_n\),求有多少 \(n\) 阶排列 \(q_1,q_2,\cdots,q_n\) 使得 \(q^k=p\)。答案对 \(998244353\) 取模。
多测,\(T \leq 10\),\(1 \leq n \leq 3000\),\(1 \leq k \leq 10^6\)。时限 \(1\) 秒。
解法:
考虑排列的 \(k\) 次方的性质。我们不妨考虑排列置换环 \(k\) 次方后的结果。
对于一个长度为 \(len\) 的环,其 \(k\) 次方后会分为 \(\gcd(len,k)\) 个长度均为 \(\dfrac{len}{\gcd(len,k)}\) 个环,证明显然。
记 \(cnt_i\) 表示 \(p\) 中长度为 \(i\) 的置换环数量。考察 \(cnt_i\) 个长度为 \(i\) 的环在原排列中对应多少个数。不难发现若有 \(c_1+c_2+\cdots+c_m=cnt_i\),且每 \(c_j\) 个环对应原排列一个环,那么我们有 \(\dfrac{len}{\gcd(len,k)}=i\) 与 \(\gcd(len,k)=c_j\)。故 \(len=ic_j\)。所以事实上这 \(cnt_i\) 个环对应原排列共 \(i \sum c_j = i \times cnt_i\) 个数。容易发现不同长度环之间不影响,尝试对每种长度环计数,然后乘在一起。
枚举环长度 \(i\),问题变为 \(c_1+c_2+\cdots+c_m=cnt_i\),将 \(cnt_i\) 个环无序划分为 \(c_1,c_2,\cdots,c_m\) 这些环,贡献是 \(\prod \limits_{j=1}^m (c_j-1)!\times (i-1)^{c_j}\),求贡献总和。\((c_j-1)!\times i^{c_j-1}\) 意义是先将 \(c_j\) 个环开头圆排列,然后每个环本身有 \(i\) 种循环同构,共 \(i^{c_j}\) 种,但是会算重所以除以 \(i\)。同时还有限制是,对于任意 \(j\),有 \(\gcd(i \times c_j,k) = c_j\)。枚举可行的 \(c_j\) 然后背包即可。
Problem Q. Toad of Immortality
题意:
给定 \(n,m\),有一组牌共 \(n+m\) 张,其中 \(n\) 张写有点数 \(1\) 到 \(n\),剩下 \(m\) 张为特殊牌。游戏按照如下进行:
- 初始时有集合 \(S\) 为空。
- 每回合在目前牌组中随机选择一张牌。若抽到的牌为写有点数的牌,将这个点数加入集合 \(S\),并将这张牌移除。若抽到的牌是特殊牌,将牌组恢复为初始的 \(n+m\) 张。
- 每回合结束后,若 \(|S|=n\),游戏结束。
求期望回合数,对大质数取模。
\(1 \leq n, m \leq 10^6\)。
解法:
首先有简单 DP,记 \(f_{i,j}\) 表示目前还剩 \(i\) 张写有点数的牌,\(|S|=j\),到达目标态的期望步数。复杂度 \(O(nm)\)。
进一步地,考虑到我们要求的其实是 \(S\) 中每个数被加入的时间的最大值期望,所以或许可以进行 Min-Max 容斥,注意这里是期望形式,即 \(E(\max \limits_{i} S_i)=\sum \limits_{T \subseteq S} (-1)^{|T|-1} E(\min \limits_{j} T_j)\)。此题中显然有 \(T\) 只和其元素个数有关。
考虑对于特定的 \(x\),求出若只有 \(n-x\) 张牌未被加入集合,那么期望多少回合使得每回合抽到的数都是这 \(x\) 张牌中的一张,令其为 \(f(x)\)。则显然有等式 \(f(x)=\sum \limits_{i=1}^x \dfrac{x^{\underline{i}}}{(n+m)^{\underline{i}}}\),其意义为枚举游戏前 \(i\) 回合没有结束的概率,然后累加。
我们考虑对这个式子化简,考虑到 \(\dfrac{x^{\underline{i}}}{(n+m)^{\underline{i}}} = \dfrac{\dbinom{x}{i}}{\dbinom{n+m}{i}}\),然后根据 \(\dfrac{\dbinom{a}{i}}{\dbinom{b}{i}}=\dfrac{\dbinom{b-i}{b-a}}{\dbinom{b}{a}}\),可以将 \(f(x)\) 化简为简单的可以 \(O(1)\) 或 \(O(\log n)\) 计算的式子,然后再进行 Min-Max 容斥即可。注意此时 \(E(\min \limits_j T_j)\) 并不等于 \(f(n-|T|)\),而是等于 \(f(n-|T|) \times \dfrac{|T|+m}{|T|}\),因为每次选出来的 \(|T|+m\) 个数中的一个只有 \(\dfrac{|T|}{|T|+m}\) 的概率选到非特殊牌。
Problem R. CF2038F Alternative Platforms
题意:
给定两个长度为 \(n\) 的非负整数序列 \(a_1,a_2,\cdots,a_n\) 与 \(b_1,b_2,\cdots,b_n\),对于一个 \(\{1,2,\cdots,n\}\) 的子集 \(S\),定义其分数 \(c(S)=\max(\min \limits_{i \in S} a_i, \min \limits_{i \in S} b_i)\)。对于 \(k=1,2,\cdots,n\),求所有大小为 \(k\) 的子集分数期望,对 \(998244353\) 取模。
\(1 \leq n \leq 2 \times 10^5\),\(0 \leq a_i, b_i \leq 10^6\),时限 \(2\) 秒。
解法:
首先对于值钦定一个顺序,值相等按照下标排。这样序列中不存在相等的数。
先考虑暴力怎么做。
假设较大的最小值取在 \(a\) 中,在 \(b\) 中的情况交换 \(a,b\) 再做一次就行。
枚举对答案产生贡献的最小值 \(a_i\),那么其余在集合内的数,其 \(a\) 值必须严格大于 \(a_i\)。记有 \(c\) 个位置符合条件,则方案数为 \(\dbinom{c}{k-1}\),但是可能存在某些选法使得最大值在 \(b\) 那边。再求出有多少 \(a_j>a_i,b_j>b_i\) 同时成立,记为 \(nc\),此时只选 \(nc\) 内的数会让最大值在 \(b\) 中取到,所以贡献为 \(-\dbinom{nc}{k-1}\),所以答案为 \(\sum \limits_{i=1}^n a_i \left(\dbinom{c_i}{k-1}-\dbinom{nc_i}{k-1}\right)\)。
\(c_i\) 和 \(nc_i\) 都是容易求的。具体的,求 \(c\) 只需要排序一遍,求 \(nc\) 只需要维护树状数组或平衡树。
现在对于固定的 \(k\),我们可以做到 \(O(n)\),所以总复杂度 \(O(n^2)\),无法通过。考虑如何优化。首先同时计算两个组合数没意义,这两个组合数形式相同,不妨考虑我们需要计算 \(\sum \limits_{i=1}^n a_i \dbinom{c_i}{k-1}\),现在 \(k\) 增加 \(1\),并不容易直接动态维护值。但是考虑直接将组合数拆开,结果为 \(\sum \limits_{i=1}^n a_i \dfrac{c_i!}{(k-1)!(c_i-(k-1))!}\)。\(\dfrac{1}{(k-1)!}\) 扔到前面,变成 \(\dfrac{1}{(k-1)!}\sum \limits_{i=1}^n a_i \dfrac{c_i!}{(c_i-(k-1))!}\)。进一步地,\(c_i - (c_i-(k-1)) = k-1\),所以这个东西可以卷积优化。对于每个 \(c_i\) 求 \(a_i\) 之和,构造多项式 \(F(x) = \sum s_i i!x^i\) 与 \(G(x) = \sum \limits \dfrac{1}{i!}x^i\),然后 NTT 即可。注意这里的卷积是下标减,取反后偏移即可。时间复杂度 \(O(n \log n)\),但是你还要对 \(nc\) 做一次,然后再对 \(b\) 做一次,总共 \(4\) 次,所以轻微卡常。
Problem S. The 2023 ICPC Asia Xi'an Regional Contest M. Random Variables
题意:
给定 \(n,m\),求所有长度为 \(n\) 的每个数不超过 \(m\) 的正整数序列的众数出现次数之和,对 \(p\) 取模。
多测,\(1 \leq n \leq 10^3\),\(1 \leq m \leq 10^9\),\(1 \leq \sum n \leq 10^4\),\(2 \leq p \leq 10^9+7\),不保证 \(p\) 为质数。
解法:
我们不妨先假设所有序列众数出现次数都为 \(n\),则此时答案为 \(n \times m^n\)。然后枚举 \(1 \leq k < n\),计算所有数出现次数不超过 \(k\) 的方案数,依次减去即可。
现在问题转变为,求有多少长度为 \(n\) 的正整数序列,每个数值域 \([1,m]\),且每个数出现次数不超过 \(k\) 的方案数。考虑直接 DP,记 \(f_{n,m}\) 表示上述问题答案,考虑转移有 \(f_{n,m}=mf_{n-1,m} - mf_{n-k-1,m-1} \dbinom {n-1} k\),意义为考虑最后一个数有 \(m\) 种方案,然后减去最后这个数出现 \(k+1\) 次的方案数。
这个 DP 直接做是 \(O(nm)\) 的,但是注意到当 \(m\) 减 \(1\) 时,\(n\) 减去了 \(k+1\),所以有意义的 \(m\) 只有 \(O(\dfrac{n}{k+1})\) 个,复杂度变为 \(O(\dfrac{n^2}{k})\),进一步总复杂度为 \(O(\sum \limits_{k=1}^{n-1} \dfrac{n^2}{k})=O(n^2 \ln n)\),适当卡常可以通过。
Problem T. CF1439D INOI Final Contests
题意:
考虑数组 \(\{ a_m \}, \{ b_m \}\),其中 \(1 \leqslant a_i \leqslant n\),\(b_i \in \{ \texttt{L}, \texttt{R} \}\)。有 \(m\) 个人和 \(n\) 个位置。\(a_i\) 表示第 \(i\) 个人希望的位置,\(b_i\) 表示第 \(i\) 个人从左到右选取位置还是从右到左。
接下来,按照 \(1 \sim m\) 的顺序选取位置,每个人根据 \(b_i\) 从某个方向开始选取位置。当他到达位置 \(a_i\) 时,如果位置 \(a_i\) 没有被占用,那么他会选取位置 \(a_i\);否则,他会接着选取第一个没有被占用的位置。
定义一对 \((a, b)\) 是合法的,当且仅当不会出现没有位置可选的情况。此时,我们认为 \((a, b)\) 的贡献是每个人实际选取的位置和位置 \(a_i\) 的距离之和。
求所有合法的 \((a, b)\) 的贡献和对 \(p\) 取模的值,\(p\) 为质数。
\(1 \leq m \leq n \leq 500\),\(10^8 \leq p \leq 10^9 + 9\),时限 \(3\) 秒。
解法:
牛完了。
考虑 \(n=m\) 怎么做,记 \(g_n\) 表示 \(n\) 个人 \(n\) 个位置的所有排列权值和。转移考虑枚举第 \(n\) 个人最终的位置 \(i\) 与他的预期位置 \(j\),显然左侧的 \(i-1\) 个人与右侧的 \(n-i\) 个人的预期位置都不能横跨 \(i\)。列出转移可以发现我们还需要求方案数。则记 \(f_n\) 表示 \(n\) 个人 \(n\) 个位置的可行排列数量。转移也是枚举最后一个人位置,可以得到 \(f_n=\sum \limits_{i=1}^n (n+1)\dbinom {n-1}{i-1} f_{i-1}f_{n-i}\),\(n+1\) 意义是对于最终落到 \(i\) 的位置的 \((a_n,b_n)\) 方案数有 \(n+1\) 个,\(\dbinom{n-1}{i-1}\) 是在剩余 \(n-1\) 个人中选左侧的 \(i-1\) 个人填 \(f_{i-1}\) 即可。\(f\) 求完后 \(g\) 是容易的。
现在考虑 \(n \neq m\),按照前面的做法,我们也应该需要记录排列数量。记 \(h_{m,n}\) 表示 \(m\) 个人,\(n\) 个位置的方案数。按照之前的枚举最后一个人是不行的,因为此时甚至不能确定最后一个的 \((a_m,b_m)\) 方案数。这里的转移很巧妙,考虑枚举这 \(n\) 个位置的极长有人的后缀即可,枚举后可以做到 \(O(1)\) 计算。类似之前的,记 \(c_{m,n}\) 表示对应的权值总和,同样的枚举极长后缀就能转移。
总复杂度 \(O(n^3)\)。
Problem U. CF2039F1 Shohag Loves Counting (Easy Version)
题意:
给定 \(m\),求有多少长度至少为 \(1\) 的,每个数不超过 \(m\) 的正整数序列,使得对于任意 \(1 \leq k \leq n\),序列所有长度为 \(k\) 的区间最大值的 \(\gcd\) 两两不同。答案对 \(998244353\) 取模。
多测,\(\sum m \leq 10^5\)。
解法:
太难了。
记序列长度为 \(n\)。考虑序列的限制非常奇怪。我们记 \(S_k\) 是所有长度为 \(k\) 的区间的最大值的集合,按照区间左端点排序。那么容易发现 \(S_k\) 等于 \(S_{k-1}\) 相邻两项取 \(\max\)。再进一步考虑设 \(g_k\) 表示 \(s_k\) 集合中所有数的 \(\gcd\),则由于 \(g_k\) 两两不同,且 \(\forall i \in [2,n],g_{i-1} \mid g_i\),所以 \(n\) 上界为 \(O(\log m)\) 量级。
进一步,有结论,对于任意 \(k \in [1,n]\),\(S_k\) 中元素两两不同。这是因为集合大小每次减去 \(1\),任意两个集合 \(\gcd\) 不同的必要条件为任意两个集合仅保留出现过的数后不同。显然若存在某个集合出现过相同的数则 \(n\) 个集合必然有两个集合去重后相同。
考虑将所有合法序列映射到一个长度为 \(n\) 的,所有后缀 \(\gcd\) 不同的递增序列上。这个序列和原始序列的 \(S\) 集合构成的集合相等。考虑对映射序列计数,可以发现对于任意合法映射序列,原始序列的数量恰为 \(2^{n-1}\)。
目标转化为求有多少长度为 \(n\),每个数不超过 \(m\),所有后缀 \(\gcd\) 两两不同的递增序列。进行 DP,枚举 \(n\),记 \(f_{i,j}\) 表示有多少第一个数为 \(i\),所有数 \(\gcd=j\) 的序列。直接转移是 \(O(m^2 \log m)\) 的,转移时维护每个数倍数的 DP 和并容斥就可以做到 \(O(\sum \limits_{i=1}^m d(i)^2 \log m)\)。
Problem V. CF1574F Occurrences
题意:
定义 \(a\) 的子段是 \([a_l,a_{l+1},\cdots,a_r]\) 的连续段构成的序列,定义 \(a\) 序列在 \(b\) 序列中出现的次数为 \(b\) 序列中与 \(a\) 相同的子段个数。
有 \(n\) 个值域在 \([1,k]\) 的数列 \(A_1,A_2,\cdots,A_n\),要求构造一个长为 \(m\) 的值域在 \([1,k]\) 的序列 \(a\),满足对于所有数列 \(A_i\),\(A_i\) 在序列 \(a\) 中的出现次数大于等于其任意一个非空子段在 \(a\) 中的出现次数。
求不同的 \(a\) 的数量,答案对 \(998244353\) 取模。
\(1\le n,m,k\le 3\times 10^5\),\(\sum c_i\le 3\times 10^5\),时限 \(7\) 秒。
解法:
简单题。
限制比较奇怪,但是仔细思考一下发现,对于第 \(i\) 个序列 \(A_i\),限制等价于 \(A_i\) 中所有数每一次在序列 \(a\) 中出现,都是与 \(A_i\) 一起出现的。同时可以发现如果 \(A_i\) 中有重复数字,那么 \(A_i\) 必然不能出现在 \(a\) 中。
然后考虑如果所有序列两两数字不同怎么做。此时序列 \(a\) 本质上就是若干个给定序列以及不存在于序列中的数拼接而成。直接 DP 是 \(O(m^2)\) 的,但是注意到本质不同长度只有 \(O(\sqrt{\sum c_i})\) 个即可做到 \(O(m\sqrt{\sum c_i})\)。
进一步地,考虑序列之间可能有重复数字。容易发现两个序列如果后缀前缀相同可以拼接。建立有向图,对于每个序列,连接相邻两个数。图中的所有链就是可以被用来拼接的。于是问题解决。