2026/07/17 赛后总结

解题报告分析3

总结遇到的问题与题目中一些神奇的思维点。

\(^{*}\):不知道的 trick 或方法

本场模拟赛题目同 2025-08-27 模拟赛,但是依然战况惨烈,得分是否不佳。同时,相较于去年,现在不少题目有和正解相似的思路,也是一种进步吧。

Write Date:7/16/2026

T1 Race

一个显然的贪心,考虑到深度路径会存在相互覆盖的情况,仔细一看发现就是长链剖分的链,跑一个长链剖分基础双 DFS 即可,时间复杂度 \(O(n\log n)\)(不知道为什么题解说会 TLE,至少这个复杂度 CCF 的少爷机肯定是 T 不了的)。

挂分原因:疑似早上没睡醒,长链剖分找重儿子的时候竟然直接比 \(v\) 的深度,而且自己还没有发现。。。绝对是睡着了。。。

T2 Count

乍得一看好像是一道组合计数好题,但是数据范围并不允许我们直接上反演或者容斥之类的。

考虑进行建模 \(^{*}\):在一个数轴上,从原点开始,可以向左走两步 \(A\) 次,走一步 \(B\) 次;向右走一步 \(C\) 次,走两步 \(D\) 次,要求一个点只能经过一次,问走到 \(S=2D+C-B-2A\) 的方案数。

似乎还是不知道怎么做。。。!注意到,\(S>0\)\(S < 0\) 是完全对称的两种情况,只需要考虑一种即可,不妨研究 \(S>0\) 的情况:

思考流程:目标是到达一个点,不妨考虑一个相似的子问题。

先考虑起始时到达点 \(1\) 的情况:

  1. 先向左移动 \(1\) 个单位,再向右移动 \(2\) 个单位;
  2. 先向左移动 \(2k\) 个单位,在向左移动 \(1\) 个单位,向右移动 \(2(k+1)\) 个单位;
  3. 先向左移动 \(2k\) 个单位,在向右移动 \(1\) 个单位,向左移动 \(2(k+1)\) 个单位;

由于我们钦定 \(S>0\),那么每次肯定都考虑向右产生贡献。最终到达结尾的情况类似。

对于中间部分的情况,画图分析一下发现不可能向左走两步,因为这样无论如何都会经过 \(i-2\)\(i-1\),而这两个点一定在到达 \(i\) 时经过过。因此中间过程只可能有三种情况:+1,+2,-1+2。这个内容可以用组合算出来,计算方式类似 Subtask3。

最后,整合一下,就是枚举开头结尾的16种情况,每次用组合记录中间部分的答案即可。

本题是一个较为复杂的分类讨论题,这个板块的确比较薄弱,经常出现分讨漏情况、分类标准重复等问题,同时这道题之前也不过,但是对整体分类讨论思路十分陌生,可见要复习一下以前踩过的坑,同时也要加强一下分讨能力。

P.S. 本题有源,原题题解 :Problem N. No Zero-Sum Subsegment

T3 Chequer

首先这是一个博弈问题,满足两人轮流执行最优操作,可以使用 SG函数。先考虑构造暴力的 SG函数:\(sg[x][y][mask]\) 表示当前在 \((x,y)\) 且已经走过的格子的集合为 \(mask\),直接按照题意暴力模拟即可,时间复杂度 \(O(NM\times 2^{NM})\)。优化一下,观察在每一行的状态,在不跳到下一行是走过的部分一定是连续的,这启发我们不需要记录所有的 \(mask\),只需要记录当前行的情况即可。

看 Subtask3(保证每行有至少一个包含障碍的格子),似乎状态的转移和障碍有关。看看现在一行可能的转移方式:

  1. 从上一行下来,可以往左往右转移
  2. 走过右边,只能往左边走
  3. 走过左边,只能往右边走

这样就可以实时转移,不用记录经过的区间了,状态量 \(O(NM)\)

那考虑没有障碍的情况呢?不妨转换一下 \(^{*}\),当一枚棋子从上一行来到下一行后,设来到了 \((x,y)\),若选择往左走,来到 \((x,y-1)\),那么相当于此时将 \((x,y)\) 变成了一个包含障碍的格子。那么对于此时 \((x,y-1)\) 的 SG 值只能由 \((x,y-2)\)\((x+1,y-1)\) 计算得到,依此类推,最终会到达 \((x,y+1)\) 处,此时就只能从下面转移过来;然后在一路回推,即可得到一行的 SG 值。考虑加速过程 \(^{*}\),注意到 SG 值为 \(0,1,2\),因此可以预处理出这样的一些信息:当 \((x,y)\) 的 SG 值为 \(v\) 时,一路向左边或右边推,位置 \((x,1)\)\((x,M)\) 的 SG 值为多少;以及当位置 \((x,1)\)\((x,M)\) 的 SG 值为 \(v\) 时,一路向右或向左推,到 \((x,y)\) 时的 SG 值为多少。

具体的,可以考虑开一个辅助数组记录这个预处理信息,设 \(g[0/1/2/3][v][k]\) 表示:

  1. \(g[0][v][k]\):由 \((x,1)\) 向右回推到 \((x,y)\),且 \((x,1)\) 的 SG 值为 \(v\) 时,\((x,y)\) 的 SG 值;
  2. \(g[1][v][k]\):由 \((x,M)\) 向左回推到 \((x,y)\),且 \((x,M)\) 的 SG 值为 \(v\) 时,\((x,y)\) 的 SG 值;
  3. \(g[2][v][k]\):由 \((x,y)\) 向左回推到 \((x,1)\),且 \((x,y)\) 的 SG 值为 \(v\) 时,\((x,1)\) 的 SG 值;
  4. \(g[3][v][k]\):由 \((x,y)\) 向右回推到 \((x,M)\),且 \((x,y)\) 的 SG 值为 \(v\) 时,\((x,M)\) 的 SG 值;

然后根据上述推导即可。

T4 Wave

首先,最暴力的想法——直接枚举每个位置上 \(b_i\) 的取值,写成一个 \(dp[i][j]\) 表示前 \(i\) 个位置上,最后一个位置的值为 \(j\) 的答案,转移很显然:

\[dp[i][j]=\min_{k=j}^{V} \{dp[i-1][k]\}+(j\ge a_i?j-a_i : C) \]

用什么单调队列优化一下,时间复杂度 \(O(nV)\)(赛上写的线段树优化,结果值域没有统一,习惯性写的树上值域为 \([1,V]\),然后挂了,时间复杂度 \(O(nV\log V)\),也能过 Subtask2)。

注意到,对于 \(j\ge a_i\) 的部分,贡献最小为 \(j=a_i\),那么不妨令每一个 \(b_i=a_j\),这样上面的状态可以优化一下。考虑对数据离散化一下,将状态变为相对位置,即:\(dp[i][j]\) 表示前 \(i\) 个位置上,最后一个取第 \(j\) 大的数字,转移基本不变,时间复杂度 \(O(n^2)\)

再次使用我们惊人的注意力,注意到 \(\min_{k=j}^{V}\{dp[i-1][k] \}\) 这个部分随着 \(j\) 的递增是单调不降的,因此 DP 值本身似乎也可以直接单调处理。因此产生一个想法:把 DP 直接挂到线段树上面维护。这样 DP 的转移可以优化到 \(\log\) 级别,最终复杂的达到 \(O(n\log n)\)(也可能是 \(O(n\log V)\)?)。

考虑新的转移的细节:
\(a_i\) 离散化后为 \(k\),有:

  1. \(dp[i][j]=dp[i-1][j]+C,k+1\le j \le n\)
  2. \(dp[i][j]=dp[i-1][j]+b_j-a_i,1\le j \le k\)

情况1和情况2的 \(-a_i\) 部分都可以直接区间修改,对于 \(+b_j\),利用发现的单调性可以得到最小值是区间右端点。那如何完成最小值的滚动?

注意到此时 \(dp\) 为两个单调不增序列首尾相连而成的,那么就可以考虑用前一个单调不增序列的最小值更新后一个,具体的,在后一个单调不增序列线段树上二分然后区间推平即可。

嗯,整体思路比较简单,包括 DP 挂到线段树上处理赛上都想到了,就是时间不够,一些细节还没有想完,整体上基本都想到了(当然,后面那个线段树上二分没有想到),所以没有写完就比较遗憾吧。

posted @ 2026-09-07 16:27  LYZHaHa  阅读(2)  评论(0)    收藏  举报