26DMYCSP-S#5

Daimayuan CSP-S 2026 Round 5

闲话

虽然是 Div.2,但是什么叫做三个半小时打穿了?

20 min 看了四个题,T1 像是简单题,T2 是不困难的构造,T3 一开始以为是点分治,后面发现两个限制都是对定点的连通块考虑的,所以看上去是不需要数据结构优化的树上 DP 题,T4 像是需要分析性质的最优化题,可能有一定码量但大概率没有太复杂的 DS。

开 T1,注意到只需要考虑当前这一段中间的数的逆序对影响,任意一个 \(i \in [l,r]\) 对 \(j \lt l\) 和 \(k \gt r\) 没有实际的变化。又因为 \(n \leq 8000\) 所以直接对着每个区间数就好了。想 + 写大概花了 10 min。

开 T2,首先考虑拍到值域上,那么问题变成了,每个点上有若干个chip,一次操作可以选择一个位置 \(i\) 保证上面的 chip 个数 \(c_i \geq 1\),然后操作令 \(c_i\) 减一并让 \(c_{i+1}\) 加一。要你最后给一个方案使得 \(1 \sim n\) 每个位置均保证 \(c_i = 1\)。这个显然可以从左往右调整,因为移动是单向的所以直接从 \(1\) 开始往 \(n\) 调整必定不劣于从中间某个地方 \(i\) 断开然后 \([1,i], [i+1,n]\) 分别调整,这样直接就做完了。想 + 写大概 20 min,不是哥们?

开 T3,首先半径的大小至多是 \(\max\limits_{1 \leq i \leq n} \text{dep}_i\),然后对一个固定的半径 \(L\),显然深度小于 \(L\) 的点不会选择 \(v_i = 0\) 那个模式,因为邻域上的点此时依旧可以完全被启动,可以在第 \(L + 1\) 层干这个事。然后对深度更大的部分就是常规树形 DP,维护三类转移即可。想 + 写大概 1h,这真不对吧?

开 T4,首先顺序是没用的,其次可以固定两维对应的操作然后对另外两维最优化。你考虑另两维最优化的过程不需要直接枚举每个点的增量,因为每次扩展都是 \(1\) 的收益所以只需要看当前哪些点还能扩展,也就是类似于相邻两点横纵坐标之差的绝对值大小,这种东西。然后考虑滑动窗口贪心优化这个就对了。有点难写,一共大概 1h 多一点过了所有大样例。

感觉纯粹就是今天题过于简单导致的。并不能反映真实的实力和问题。


T1

tag:贪心、枚举。

考虑翻转一个区间对所有逆序对数量的影响,设当前翻转的区间是 \([l,r]\),对于 \(i \lt j, p_i \gt p_j\),如果 \(i \lt l \leq j \leq r\),那么不会有影响,\(j \gt r\) 同理。所以只有 \(l \leq i \lt j \leq r\) 这样的逆序对才会被整个翻转过来。

那么问题转化为区间逆序对数,可以直接枚举每个子区间计算,简单来说就是先枚举左端点 \(l\),然后右端点 \(r = l, l + 1, \dots, n\) 这样一遍扫过去,用一个桶记录逆序对即可。时间复杂度 \(\mathcal{O}(n^2)\)。

ac link


T2

tag:贪心、构造。

可以直接将 \(a_{a_i} \leftarrow a_{a_i} + 1\) 这种操作转化到值域上。那么问题变成,有 \(n\) 个位置,第 \(i\) 个位置上写着一个数 \(c_i\),保证 \(\sum_{i=1}^{n} c_i = n\),你每次可以选择一个位置 \(1 \leq i \lt n\) 满足 \(c_i \neq 0\) 然后令 \(c_i \leftarrow c_{i} - 1\) 并且 \(c_{i+1} \leftarrow c_{i+1}+1\),要求你构造出一个方案,使得最终对每个位置 \(1 \leq i \leq n\) 都有 \(c_i = 1\)。

因为移动是单向的,只能往更大的位置上移动,所以直接贪心,考虑 \(i = 1, 2, 3, \dots, n\),如果当前 \(c_i \gt 1\) 就把这个位置上的 \(c_i - 1\) 都转移到 \(i + 1\) 去,邻项交换一下不难证明这是充要的,最多操作次数考虑 \(c_1 = n\) 的情况,是 \(\frac{n(n - 1)}{2}\)。时间复杂度 \(\mathcal{O}(n^2)\)。

ac link


T3

tag:树形 DP,贪心。

对一个给定的 \(L\),以 \(k\) 为根计算每个点的深度 \(\text{dep}(u)\),则所有 \(\text{dep}(u) \lt L\) 的位置肯定不会选择第三类操作(就是把当前位置权值置为 \(0\)),因为不这么做它邻域内所有节点也都能被激活。

所以这些节点独立的贡献是 \(\max(m_u, w_u)\),删除它们之后,所有深度为 \(L\) 的节点对应一棵独立的子树,这个根节点是可以直接取到 \(\max(m_u,w_u)\) 的,只需要考虑子树内其他点的贡献。

则可以直接对这棵树做 DP,简单来说就是 \(f(u,0/1/2)\) 对应以 \(u\) 为根的子树,该节点选(\(0\))或不选第三类状态,以及是否存在父节点传下来的可以激活的条件(\(1/2\))。然后转移分别是:

  • 如果 \(u\) 自身选第三类状态,则所有子节点都可以激活。有 \(f(u,0) = \sum_{v \in \text{son}(u)} \max(f(v,0), f(v,2))\);
  • 如果 \(u\) 取得激活条件但自己不是第三类状态,当前这个点贡献为 \(\max(w_u,m_u)\),子树的贡献是 \(\max(f(v,0), f(v,1))\)。也就是 \(f(u,2) = \max(w_u,m_u) + \sum_{v \in \text{son}(u)} \max(f(v,0),f(v,1))\).
  • 如果 \(u\) 不是第三类状态也没有激活条件,一种情况是直接选 \(m_i\) 然后无所谓,子节点就是 \(\max(f(v,0),f(v,1))\),另一种是强制选一个损失最小的子节点,让他变成第三类情况,然后我取到 \(w_u\),这个对应的就是选出的那个子节点变成 \(f(v,0) - \max(f(v,0),f(v,1))\),其余转移不变。汇总起来就是

\[f(u,1) = \max\left \{ m_u + \sum_{v \in \text{son}(u)} \max(f(v,0),f(v,1)), w_u + \sum_{v \in \text{son}(u)} \max(f(v,0),f(v,1)) - \\ \max\limits_{v \in \text{son}(u)} (f(v,0) - \max(f(v,0), f(v,1))) \right\} \]

直接对着这个转移就好了,求出 \(f(u,0/1/2)\) 之后往 \(\text{dep}(u)\) 对应的深度上贡献就做完了,需要注意 \(L \gt \max\limits_{1 \leq u \leq n} \text{dep}(u)\) 的情况,此时等价于取到深度最大值。时间复杂度是 \(\mathcal{O}(n + q)\)。

ac link


T4

tag:贪心、单调队列。

感觉就是,一堆贪心凑在一起,合成大西瓜。

首先容易注意到操作顺序没有影响,只和每个方向上的操作次数有关,这个很好理解因为最后必定会形成操作次数对应的矩形。那么最简单的思路就是直接枚举四个方向上分别有多少次操作。

然后你考虑优化,先考虑一维怎么做,比方说我固定了上下操作的次数分别为 \(u,d\),那么左右操作的次数 \(l,r\) 其实是由任意两个点(包括和左右边界)之间的最远距离确定的。具体来说,讨论一行,取出所有点横坐标并从左到右排序,记为 \(x_1,x_2,\dots,x_k\),则需要满足约束 \(l \geq x_1 - 1, r \geq R - x_k\) 并且需要确保 \(l + r \geq \max\limits_{1 \leq i \lt k} x_{i + 1} - x_i\)。然后你又发现其实不需要考虑所有 \(R \times n\) 个点对应的行列,对于原始点离散化后的空隙(也即两行两列之间的位置),如果被染色必定是用原始点上下移动产生的点来染色。所以只需要考虑所有 \(y - u\) 和 \(y + d + 1\) 这种位置上的点,离散化可以直接做到 \(\mathcal{O}(n^2)\),那么此时只剩下 \(u,d\) 对应的 \(R\) 了。

此时你注意到,因为实际有效的状态只有 \(\mathcal{O}(n^2)\) 个,所以 \(u,d\) 也只需要考虑会使得整体状态变化的 \(\mathcal{O}(n)\) 个分界点。也就是只需要考虑离散意义下,刚刚说的两种行移动对应的分界点,你可以刻画为 \(u,d\) 操作第一次和行内操作有交的点,这样的关键点数量是 \(\mathcal{O}(n^3)\),则可以直接枚举关键点做到 \(\mathcal{O}(n^5)\)。

此时你发现很难搞了因为要同时枚举 \(u,d\) 然后另一维肯定不能做到 \(\mathcal{O}(1)\),筑波筑波我不想写带 \(\log\) 的东西怎么办呢,考察两个相同列的关键点 \(i,j\),它们之间的空白行,本质不同的状态只和 \(u + d\) 相关,所以考虑直接枚举 \(u + d\),不难注意到为了将整个网格都染色,只需要看所有形如 \(y_i - y_j - 1\) 状物或者 \(y_i - y_j + R - 1\) 状物的 \(u + d\) 即可。它本质就是要确保两个关键点之间的行恰好均被填充,所以必定是恰好填满最宽的那个空隙,可以进一步做到 \(\mathcal{O}(n^4)\)。

此时不难想到可以从增量的角度考虑这个问题,每个原有的点都覆盖了它上或下 \(u + d\) 宽度的一个矩形,因此可以直接对不同行做我们刚刚对列那一维的优化,也就是只需要实时维护当前有交的上下边界,然后滑动窗口维护最宽的区间的大小即可,这样就做到了 \(\mathcal{O}(n^3)\)。

ac link


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