26DMYCSP-S#8
Daimayuan CSP-S 2026 Round 8
闲话
看上去以后 Div.2 都会变成挂分大赛了,不过 CSP-S 之前多出点这种比赛貌似不是坏事?
20min 看了四个题,T1 像是需要一点手法的签到,T2 像是简单动脑题,T3 像是比较传统的字符串,T4 像是重心放在拆贡献上的数数,不确定难度但应该不会太非常规。
开 T1,注意到直接从右往左单调栈维护所有不交的面积即可,一共 20min 左右。
开 T2,注意到可以转化为数轴上的点集匹配问题,对于 \(A_i \geq B_i\) 的肯定是直接贪心匹配,唯一的问题是逆序对怎么处理。注意到必定是走一段区间并拿完上面所有的点再折返回去,所以可以直接对着这个过程 DP,拆一下贡献变成维护前缀 min 可以做到线性,大概花了 30min。
开 T3,显然是要从后往前贪心,枚举当前串的所有非空后缀,拼接到现在答案的前面,看哪个会让字典序变得最小。那么问题变为快速判断两个串字典序,二分 + 哈希即可。对应的无论是字符串尾加元素还是字符串首加元素都可以通过对应的哈希递推做到总复杂度 \(\mathcal{O}\left(\sum |S_i|\right)\)。大概花了 1h,主要是双哈希有点难写,最后还是被挂分了。
开 T4,首先可以计数转概率,问题变为随机一个子集操作然后乘上 \(2^q\)。因为 \(x \leq 2^7\) 又是异或操作所以自然想到拆位,计算贡献的式子平方拆开,那么你稍微分讨一下就可以直接把贡献转到二维矩阵加,单点查状物。一共 1h30min 左右。
赛后发现写的双哈希 \(P_1 = 1004535809, P_2 = 10^9 + 9\) 被卡了,不是这有点变态了,怀疑是 codex 造的数据,然后它可能认为非确定性算法都是假做法所以造了一大车数据,以后还是尽可能用随机质数做模数。\(100 + 100 + 55 + 100 = 355\),rk 23,现在累计需要起飞 \(0.45\) 次。
T1
tag:单调栈。
简单来说就是因为输出两倍面积,并且斜边对应的斜率是相同的,所以算贡献的时候可以直接扩成一个矩形状物。直接设每个点的右端点 \(r_i = i + d_i\),那么从后往前考虑,单调栈维护后缀中所有未被完全覆盖的矩形,每次加入一个新矩形的时候,弹出单调栈内所有被该矩形严格包含的矩形并删去它们造成的贡献,那么新矩形造成的贡献是可以直接通过上一个未被完全覆盖的矩形,即当前栈顶求出的。设该点为 \(j\) 那么贡献就是 \(\min(j, r_i) \times (2r_i - i - \min(j, r_i))\)。
直接可以做到 \(\mathcal{O}(n)\)。
T2
tag:DP,贪心。
因为两种点是一一匹配的所以可以直接考虑贪心地让标号为 \(i\) 的两个点匹配在一起。
如果 \(A_i \geq B_i\) 那么一定可以顺着走过去,对这种点对可以直接删去,它不对答案产生额外贡献。
假设剩下来的点是 \(a_1,a_2, \dots, a_k\) 以及 \(b_1, b_2, \dots, b_k\),那么每次决策必定是枚举一个区间,将区间内所有 \(b\) 都拿完然后匹配对应的 \(a\),考虑每个单位长度的经过次数可以简单证明折返必定不优。这个可以直接 DP,设 \(f_i\) 表示处理全部前 \(i\) 个点,此时在点 \(i\) 对应的代价,有转移 \(f_i = \min\limits_{1 \leq j \leq i - 1} \{f_j + (b_i - a_j) + (b_i - a_{j + 1}) + (a_i - a_{j + 1})\}\),最终答案就是要么直接走到最后一个,要么先走到最后然后倒回来,取 \(\min\) 即可。
容易注意到固定 \(i\) 之后,\(i,j\) 的贡献可以直接拆开,对应一个前缀 \(\min\) 状物,那么可以直接通过维护这个前缀 \(\min\) 做到 \(\mathcal{O}(n)\)。
T3
tag:字符串,哈希,贪心。
因为是字典序,对一个当前选取的字符串片段,它选什么样的后缀只和这个后缀本身有关,因此可以想到从后往前贪心。
那么我们可以考虑固定 \(i + 1 \leq j \leq n\) 对应的 \(s_j\) 选取了哪些子段作为答案,然后看 \(s_i\) 该怎么选。那其实就是要找出 \(s_i\) 的某个子段接上一个固定后缀以后,字典序最小的串。
这个可以直接哈希 + 二分,简单来说就是维护所有 \(s_j\) 所选答案拼在一起那个串的哈希值,这样当我们需要比对两个串 \(s_{i,[l_1,r_1]}\) 和 \(s_{i, [l_2,r_2]}\) 字典序的时候,等价于比较两个部分:
- 对于 \(p \in [1,\min(r_1 - l_1 + 1, r_2 - l_2 + 1)]\) 的部分,直接比较两个子段自己的哈希值。
- 对于 \(p \in [\min(r_1 - l_1 + 1, r_2 - l_2 + 1) + 1, \max(r_1 - l_1 + 1, r_2 - l_2 + 1)]\) 的部分,短的那个串要比较的其实就是已经确定的答案后缀的 \(p - \min(r_1 - l_1 + 1, r_2 - l_2 + 1)\) 位。
所以你发现无论是 \(s_i\) 自己的哈希值,还是后缀答案对应的哈希值,都是可以 \(\mathcal{O}(\sum |s_i|)\) 递推的,并且需要确定的值来比较的时候都是可以准备好的不存在因为后效性求不了的问题。
需要双哈希,而且注意到这个拼接极端情况下可以到 \(2 \times 10^6\) 而不是单个串最大值 \(10^6\)。时间复杂度 \(\mathcal{O}\left(\sum |s_i| \log \left(\sum |s_i|\right)\right)\)。
T4
tag:组合计数、位运算。
首先注意到几个需要注意到的观察:
- \(x_i \leq 127\),并且异或操作显然可以拆位讨论贡献。
- 每个操作等概率随机挑选,对全集计数,所以可以计数转概率,最后乘 \(2^q\)。
- 考虑它的贡献对应的是啥,区间和的平方展开可以得到只和有序对 \(i \lt j\) 相关的项,平方项可以 \(\mathcal{O}(n)\) 自己算,两数之积的部分的系数是包含这两个下标的区间数量,也即 \(\min(i, j) \times (n - \max(i, j) + 1)\)。
所以只需要将区间贡献按位进一步拆开,因为值域上只有 \(7\) 位,所以只需要枚举两个二进制位 \(x, y\) 然后分讨等概率随机意义下,它对 \(2^{x + y}\) 的系数的贡献,实际上有都不翻转、只翻转第一个、只翻转第二个、都翻转四种情况,对同一类非 \(0\) 类型的操作,最终取值只取决于选中翻转数量的奇偶性,只要某一类存在那么奇偶概率就均为 \(1/2\),因此只需要看哪些类型存在:
- 没有任何一类,此时两个位置均保持原来的取值。
- 只有其中一类,不翻转和只翻转这个类型各占 \(1/2\),当且仅当其中一种可以凑出两个 \(1\) 概率就均为 \(1/2\),否则全为 \(0\)。
- 有至少两类,此时无论怎么翻转肯定能凑出四种等概率的状态,所以概率就是 \(1/4\)。
那么此时只需要统计每种翻转类的出现次数,可以只记前两种情况对应的次数,那么可以直接容斥出第三种情况。前两种情况可以按位做差分求出,对同时翻转两个位置的情况,可以固定点对然后考虑对每个操作区间,当且仅当使得两个位均为 \(1\) 的操作被包含于当前区间,才对这类情况产生贡献,这个等价于一次二维差分。
则可以求出三类情况之后直接计算对应的贡献,时间复杂度 \(\mathcal{O}((q + n^2) \log^2 x)\)。
浙公网安备 33010602011771号