2025.7.28 - 8.2
Question 1. 「2024 “钉耙编程” Round.1」D. 传送
给定 \(n\) 个点 \(m\) 条边的无向图 \(G\),第 \(i\) 条边连接 \(u_i,v_i\) 两点,出现在 \([l_i,r_i]\) 时间段内。
总时间段为 \([1,n]\),对 \(k = 1,2,\cdots, n\) 求点 \(1\) 与点 \(k\) 连通的时间点的总和。
\(n,m\leq 6\times 10^5\)
容易想到线段树分治+可撤销并查集,问题是如何执行连边时的连通块加。
在并查集的节点上打 tag,返祖链上的差分-前缀和,每次撤回时把 tag 下传即可,保持时间复杂度不变。
时间复杂度为 \(\mathcal{O}(m\log_2^2 n)\)。
Question 2. 「2024 “钉耙编程” Round.1」F. 序列立方
给定一个长度为 \(n\) 的正整数序列 \(A\),求 \(A\) 中所有非空子序列(不一定连续)的出现次数的立方和。
\(n\leq 250\)
原问题等价于从 \(A\) 的所有子序列中选择三个相同的子序列的方案数。
设 \(f_{i,j,k}\) 表示以 \((a_i,a_j,a_k)\) 这三个元素结尾的相同子序列组的方案数,则暴力转移为:
这个东西可以三维前缀和优化,时间复杂度变为 \(\mathcal{O}(n^3)\),注意初始化!
Question 3. 「2024 “钉耙编程” Round.1」E. 博弈
Kaho & Suzune 又来玩游戏了,现在有一个小写字母的可重集合 \(S\),两人分别持初始为空的字符串 \(A,B\),从 Kaho 开始,每一轮:
- Kaho 从 \(S\) 中等概率选择一个字符,并取出,追加到 \(A\) 的末尾。
- Suzune 从 \(S\) 中等概率选择一个字符,并取出,追加到 \(B\) 的末尾。
若 \(A\) 的字典序严格大于 \(B\),则 Kaho 胜,求其胜率。
\(T\leq 10^4, |S|\leq 10^7\)
如果这是概率,那么这个博弈就是皇帝的博弈,实际上就是概率期望题。
假定最终的某种情况的 \(A,B\),且 Kaho 胜,那么用你的大手换掉 \(A,B\),发现 Kaho 就失败了,而从最初的情况得到 \((A,B)\) 与 \((B,A)\) 的概率相等。
故 Kaho 与 Suzune 有相同的胜率!
考虑如何计算平局的概率,设 \(O\) 为出现奇数次的字符数量,如果 \(O \ne 0\),无论怎样都是不可能平局的。
如果 \(O = 0\),则相当于是一个多重组合的式子,假设 \(s_i\) 即字符 \(i\) 的出现次数,\(m\) 为 \(|S|\)。
所有的 \(/2\) 全部为下取整,所以胜率为 \(\frac{1-p}{2}\)。
如果 \(O = 1\),则需要考虑把出现了奇数次的字符拿出来,这个给 Kaho 用,之后问题规约为 \(O = 0\),但是此时的平局剩下一个字符,Kaho 拿到字符后字符串变长变为赢家,故此时胜率为 \(\frac{1+p}{2}\)。
时间复杂度主要为 \(\mathcal{O}(|S|)\) 的预处理。
Question 4. 「2024 “钉耙编程” Round.1」J. 众数
给定一长度为 \(n\) 的正整数数列,其中 \(A_i\) 在 \([1,n]\) 中等概率生成,\(q\) 组询问,每一组询问给出区间 \([l,r]\),询问如下内容:
- 设 \(S = \{\underset{p\leq i\leq q}{\max} A_i \mid l\leq p\leq q\leq r\}\),求 \(S\) 中的最大的众数。
\(T\leq 3, n,q\leq 2\times 10^5\)
在等概率生成 \(A\) 的前提下,则答案一定比较大,设 \(K = 50\),只考虑区间前 \(K\) 大。注意这里是严格的前 \(K\) 大,即出现多次的数只认为是一个。
首先来到问题 1:如何求解区间前 \(K\) 大?。
考虑在线段树的每一个节点上维护这个区间内的前 \(K\) 大,随后合并时归并即可。
接下来是问题 2:如何检查前 \(K\) 大中的每一个数,其作为最大值的区间数量?
考虑用堆维护区间,按照最大值从大到小依次取出每一个区间 \([l,r]\),找到区间中的最大值 \(v\) 与出现位置 \(p\),那么 \(v\) 的区间数量增加 \((p-l+1)(r-p+1)\) 个,随后分裂 \([l,r]\) 成 \([l,p), (p,r]\) 再加入堆。
每次 check 的时候,设 check 的值为 \(v\),取出所有最大值为 \(v\) 的区间计算总区间数量即可。
当然,求区间最大值及其位置用 ST 表,不要用前面那颗线段树,否则会超时,时间复杂度可能是 \(\mathcal{O}(nK\log_2 n)\)。
Question 5. 「2024 “钉耙编程” Round.1」G. 三元环
给出 \(n\) 个二元组 \((f_i,g_i)\),建立一张有向完全图 \(G\),对于 \(i,j(i < j)\) 之间的边,若 \(f_i < f_j, g_i < g_j\),则连边为 \(i\to j\),否则为 \(j\to i\)。
求 \(G\) 中三元环数量。
\(n\leq 2\times 10^5, f_i,g_i\in [1,n]\)
由于这是有向完全图,所以任意三个互不相同的点 \(x,y,z\) 之间无非两种情况:
- 是一个三元环。
- 存在恰好一个点,该点连向另外两个点(或者是另外两个点都连向它)。
假设点 \(i\) 的入度为 \(I_i\),那么情况二无非就是枚举这个点 \(u\),然后选出两个点 \(v,w\),于是总方案数为
故答案为
考虑如何求 \(I_i\),分 \(j < i\) 与 \(j > i\) 讨论:
- 当 \(j < i\) 的时候,方向为 \(j\to i\) 当且仅当 \(f_j < f_i, g_j < g_i\),故需要对 \(i\) 计算这样的 \(j\) 的数量 \(X_i\),可以 CDQ 分治搞定。
- 当 \(j > i\) 的时候,方向为 \(i\to j\) 当且仅当 \(f_i < f_j, g_i < g_j\),故需要对 \(i\) 计算这样的 \(j\) 的数量 \(Y_i\),若需要求 \(j\to i\) 的数量,可以用 \(n-i - Y_i\) 来计算,依旧可以用 CDQ 分治。
于是 \(I_i = X_i + (n - i - Y_i)\),问题得以解决。
时间复杂度为 \(\mathcal{O}(n\log_2^2 n)\)。
Question 6. 「CCC 2017 S5」地铁交通
给定长度为 \(n\) 的正整数序列 \(A\),以及 \(m\) 个环,每个环至少包含一个元素,维护以下两种操作共 \(q\) 个:
1 l r
,表示求 \(A\) 的区间 \([l,r]\) 内的所有元素的和。2 x
,找出编号为 \(x\) 的环,设该环所包含的元素的下标从小到大分别为 \(p_1,p_2,\cdots, p_k\),然后:- \(\forall 1\leq i < k\),将 \(A_{p_{i+1}}\) 赋值为 \(A_{p_i}\),将 \(A_{p_1}\) 赋值为 \(A_{p_k}\)。
- 所有赋值操作同时完成。
\(m\leq n\leq 1.5\times 10^5, q\leq 1.5\times 10^5\)
无脑一点,首先根号分治,对大环与小环分别处理。
对小环,在修改的时候,暴力即可,由于有 \(\mathcal{O}(B)\) 个元素,开一个修改 \(\mathcal{O}(1)\) 查询 \(\mathcal{O}(\sqrt{n})\) 的分块平衡一下。
对大环,在询问的时候,枚举暴力计算,这里唯一的 \(\log\) 在于求 \([l,r]\) 在环上的覆盖区域,使用离线即可去掉。但是保留也无所谓,跑的也非常快。
具体来说,把所有操作离掉,然后枚举每一个大环,把所有操作和询问拉出来做一遍。
视 \(n,q\) 同阶,则时间复杂度为 \(\mathcal{O}(n\sqrt{n\log_2 n})\) 或 \(\mathcal{O}(n\sqrt{n})\)。