26DMYCSP-S#1

Daimayuan CSP-S 2026 Round 1

T1

tag:DP、排列计数、状态合并

这类型排列计数肯定是要考虑连续段 DP 的,简而言之就是从值域角度考虑,从小到大把每一个取值填进去,计算对应局面的方案数。考虑求出每个区间的长度 \(s_1,s_2,\dots,s_k\),从小到大将每个数 \(i = 1, 2, 3, \dots, n\) 放进尚未填数的位置。假设当前已经放了 \(i\) 个数,当前要放 \(i + 1\):

  • 可以开一个新段,那么 \(i + 1\) 必定是该区间最小值,选择位置的方案数为对应的 \(s_j\),权值固定为 \(i+1\)。
  • 可以放进一个已有的段,那么这个段对应的权值是不变的。

那么可以直接状压,设 \(f(S,i)\) 表示有且仅有集合 \(S\) 中的区间已经确定最小值,同时值域扩展到 \(i\)。那么求出 \(w_{S}\) 表示 \(S\) 对应区间长度之和。有转移 \(f(S,i + 1) \leftarrow f(S,i) \times (w_{S} - i)\) 以及 \(f(S \cup \{j\}, i + 1) \leftarrow f(S,i) \times s_j \times (i + 1)\)。分别对应了放进已有段和开新段的转移。这样是 \(\mathcal{O}(nk2^k)\) 的。

然后你注意到对于两个长度相同的区间,本质是没有区别的,不需要一开始把他们划分出来,而只需要在完全确定的时候求出把这样的区间放在所有可选位置的方案数。所以对每个 \(s_j\) 求出 \(x_j\) 表示一共有多少个长度为 \(s_j\) 的区间,以及 \(c_j\) 表示其中已经填入最小值的区间有多少个。那么将状态按照 \(x_j\) 混进制状压之后,有转移:

  • 放进一个已有区间,\(f(S,i+1) \leftarrow f(S,i) \times \left(\sum_{j=1}^{n} c_j \times s_j - t\right)\)。
  • 新开一个区间,\(f(S+\Delta_j,i+1) \leftarrow f(S,i) \times (x_j - c_j) \times s_j \times (i+1)\)。

因为区间长度不超过 \(100\),所以实际总状态数为 \(\prod (c_i + 1)\),至多为 \(2 \times 10^5\),可以通过。

时间复杂度 \(\mathcal{O}(n \times c \times S)\),其中 \(S\) 表示状态总数,\(c\) 表示不同的长度种类数。


T2

tag:倍增、哈希、贪心

首先肯定只需要保留从点 \(1\) 到每个点的最短路图,也即每条转移边 \((u,v,w)\) 都有 \(\text{dis}(v) = \text{dis}(u) + w\),显然这样的边是单向边而且整张图是 DAG。

然后有一个比较人类的思路,就是我们对每个节点只需要保留前 \(2\) 小的路径对应的转移,所以只需要对每个节点的这两条路径保留前驱编号、最后一条边对应编号、路径长度(以确保这种转移确实是最短路)。比较两条路径的时候可以直接用树上倍增找到他们的最长公共前缀,设路径哈希为 \(H_u = H_{p} \times B + \text{id}\),其中 \(p\) 表示前驱节点,\(\text{id}\) 表示边的编号。进而通过做差我们可以取出前缀哈希值,则可以直接二分+哈希找到第一个哈希值不同的位置 \(k\) 然后比较第 \(k\) 条边的权值。这样做是 \(\mathcal{O}((n + m) \log^2 n)\) 的。

一个更加优秀的思路是,注意到上面思路本质是对最短路 DAG 找一棵搜索树,确保每条边都是 \(\text{id}\) 从小往大连,则会有若干横叉边,注意到一条答案路径至多经过一条横叉边,否则调整法可以证明这条多出来的边一定在搜索树上。所以可以直接对每条横叉边更新答案,然后从 \(1\) 开始按照边数 \(\rm BFS\) 序扩展下去,这样是 \(\mathcal{O}((n + m) \log n)\) 的。

当然还有一个变态思路,只需要在这张 DAG 上 \(\rm DFS\),每次按照编号从小到大遍历每条出边,这样能确保搜索过程中路径的字典序是递增的,则只需要用类似多路归并剪枝的思路,确保每个点至多被遍历两次即可。因为被遍历一次至少能扩展出以该点为基础的,必定合法的至少一种路径,所以这样必定不会出现某个后面的点只被遍历一次的情形。直接这么做就是 \(\mathcal{O}(n + m)\) 的。


T3

tag:扫描线、代数变换、堆

首先可以拆 \(\sum_{i=1}^{m-1} \sum_{j=i+1}^{m} (y_i-y_j)^2\) 这个式子,你考虑固定 \(i\) 将 \(y_i^2\) 和对应系数 \(m - i\) 对应上,同理另一侧将 \(y_j^2\) 和系数 \(j - 1\) 对应上,两个一次项相乘的部分提公因式出来得到 \(m \times \sum_{i=1}^{n} y_i^2 - \left(\sum_{i=1}^{n} y_i \right)^2\)。而这恰好是方差的 \(m\) 倍。组合意义是容易理解的,考虑方差是对 \(y_i\) 和 \(\frac{\sum_{j=1}^{m} y_j}{m}\) 做差,所以每一项的底数部分有 \(m\) 倍差距。同时因为每个数地位相等地作为 \(i\) 和 \(j\) 所以二者抵消之后符号上不会有变动,又因为两个一次项部分的组合也是齐次的所以两侧的贡献也会抵消,最终一一对应上公差的项并且全部带一个 \(m\) 的系数。

所以此时我们可以反过来固定 \(\frac{\sum_{j=1}^{n} y_j}{m}\) 从而转化为选取 \(y_i\) 使得 \(\sum_{i=1}^{m} \left(y_i - \frac{\sum_{j=1}^n y_j}{m}\right)\) 尽可能小。对一个固定的平均数 \(v\) 我们可以直接对每个颜色选取离 \(v\) 最近的点,类似于分颜色做多路归并将所选点集大小控制在恰好为 \(m\)。

那么自然地想到对 \(v\) 做扫描线,对每个颜色维护出从小到大按 \(x\) 排序之后的直接前驱和后继,这个因为总颜色数是 \(\mathcal{O}(n)\) 的所以可以直接一遍 \(\mathcal{O}(n)\) 递推得出。然后对 \(v\) 做扫描线的过程中只需要实时维护多路归并,对当前的 \(v\) 如果用某个颜色的后继替换任意颜色的前驱后仍合法并且答案更小就进行替换。因为 \(v\) 也即统计意义下的中点移动方向单调不降,所以可选的最优点位置也必定单调不降,故每个点出现在集合内的时间一定是一整个连续区间,直接用堆来维护当前可能选择的点集即可,因为每个点至多入堆/出堆一次,所以时间复杂度 \(\mathcal{O}(n \log n)\)。


T4

tag:贪心、博弈论、分治、bitset

首先注意到 \(k \gt 2\) 的情况是诈骗,因为两个人可以轮流撤销对面的操作所以任意新增操作都一定不优。因此可以直接分 \(k\) 奇偶讨论,问题转化为 \(k = 1, 2\) 怎么做。

这个 \(a_i \leftarrow X - a_i\) 的形式不好处理,考虑构造 \(b_i = X - 2a_i\),那么一次操作就等价于直接对 \(b_i\) 取反,两人目标变为让 \(\sum_{i=1}^{n} b_i\) 最大/最小,最后再加上原始 \(a_i\) 之和即为答案。对于 \(k = 1\) 就是简单的最大子段和问题,可以直接 \(\mathcal{O}(n)\),对于 \(k = 2\) 由于可能出现操作区间重叠的情况所以不是简单的找一个区间翻转最大另一个最小然后直接做差状物。考虑设出 Alice 的选取区间 \([l_1,r_1]\) 以及 Bob 的区间 \([l_2,r_2]\),那么存在 \(\binom{4}{2} = 6\) 种相对位置。相对的我们可以利用三个信息:前缀最大/后缀最大/区间最大来刻画所有可能的最大子段和结构,设 \(b_i\) 前缀和序列为 \(p\),用分治解决一维对应的限制,设中点 \(l-1 \leq m \lt y\),\(L_x = p_x - \max\limits_{0 \leq t \lt x} p_t\),同理有 \(R_x = \min\limits_{x \leq t \leq n} p_t - p_x\)。由此可以详细构造出:

\[\begin{align} \nonumber A_1(l) &= \min\{\text{Minsub}(1,l) - p_l, -p_l - \text{Maxsub}(l+1,m),L_{l} - \max\limits_{x \lt t \leq m} p_t\};\\ \nonumber B_1(r) &= p_r;\\ \nonumber A_2(l) &= -p_l;\\ \nonumber B_2(r) &= \min\{p_r + \text{Minsub}(r + 1, n), p_r - \text{Maxsub}(m+1,r), \min\limits_{m \lt t \lt r} p_t + p_r\};\\ \nonumber A_3(l) &= \min\{L_l,\min\limits_{l \leq t \leq m} p_t - p_l\};\\ \nonumber B_3(r) &= R_r;\\ \nonumber A_4(l) &= \min\{L_l,\min\limits_{l \leq t \lt m} p_t - p_l\};\\ \nonumber B_4(r) &= p_r - \max\limits_{m \lt t \leq r} p_t \end{align} \]

那么 Alice 选一个区间对应的代价就变成了 \(F(l,r) = \min\limits_{1 \leq j \leq 4} \{A_j(l - 1) + B_j(r)\}\)。这些在分治过程中是可以线性扫描得出的,于是固定答案下界 \(z\),则只需要对每个右端点判断是否存在左端点,满足 \(A_j(l - 1) \geq z - B_j(r)\) 即可。而这等价于每个维度上都会给出一个合法的左端点集合,查询只需要将这四个集合 bitwise AND 起来,考虑按长度 \(B\) 分块存 bitset,这样取出对应集合后只需要暴力检查至多 \(4B\) 个元素,所以单次查询时间复杂度 \(\mathcal{O}\left(\frac{n}{w} + B\right)\)。进一步分析我们发现不需要固定 \(z\),因为本质要求的是 \(\max\limits_{l \leq x \leq m} A_j(x) + \min\limits_{m \lt y \leq r} B_j(y)\),所以可以转化为,找到对应维度中,一个右端点集合能取到最小值的区间对应的最右侧左端点集合。所以这样分治内部就是不带固定下界的 \(\mathcal{O}\left(\frac{n}{w} + B\right)\),也即总复杂度 \(\mathcal{O}\left(\frac{n^2}{w} \log n + B \log n\right)\),用块长平衡一下常数即可做到 \(\mathcal{O}\left(\frac{n^2}{w}\right)\)。


posted @ 2026-09-27 18:44  Twistedmind  阅读(6)  评论(0)    收藏  举报