2024集训D4总结

集训D4总结

模拟赛

T1(博弈/打表)

题意

\(Nim\) 游戏 , 但是先手 \(A\) 每次执行一次操作 , 而后手 \(B\) 执行两次 . \(T\) 次询问先手胜负 .

题解

打表思路 首先打表用的暴力是显然的 . 分析数据时 , 可以容易地看出 \(1\) 有特殊意义 . 此外 , 当非 \(1\) 数较多时 , 结果都是后手胜 . 发现观察并不难 , 得出 :

  • \(1\)\(\ge 3\) 时后手胜 .
  • \(1\)\(=2\) , 但是不存在 \(2\) 时也后手胜 .
  • \(1\)\(=1\) , 先手胜 .
  • 全为 \(1\) , 若 \(n\mod 3=0\) 后首胜 , 否则先手胜 . 这一点容易发现 .

这是比较显然的结论 , 进一步观察没有确定的 \(=2\) 且没有 \(2\) , 可以猜到和 \(n\mod 3\) 也有关系 , 发现此时 \(n \mod 3=2\) 时后手胜 , 否则先手胜 .

这些规律足够显然以从打表中得到 . 因此打表是可行 , 甚至是最优解 .

正向分析 首先需要以发现 \(1\) 不平凡 为基础 .

考虑从最简单情况一点点讨论 :

  • 全为 \(1\) , 显然双方的策略只能逐一拿 , 也就是与 \(\mod 3\) 有关 .

  • 有一个非 \(1\) 数 , 发现假如先手拿这个数 , 可以取到 \(0\)\(1\) , 这样不仅转化成了上一张情况 , 还有两种不同选择 , 因此先手必胜 .

  • 有两个非 \(1\) 数 , 因为取 \(1\) 会进入平凡情况 , 仍然先考虑取非 \(1\) 数 , 设为 \(x,y\) .

    • 尝试向 B 的下一步分析, 假设不取到 \(1\) , 到 B 时仍然有 \(x,y\ne 1\) , 发现 B 对这两个数的操作很自由 , 这两个数完全可以转化为 \(0,1,2\)\(1\) , 这样有 \(3\) 个不同方式进入全 \(1\) 状态是必胜的 .
    • 那么只能考虑把一个取到 \(1\)\(0\) , 那么到 \(B\) 时有 \(x\ne 1\) , 发现 \(B\) 仍然可以贡献出多种取 \(1\) 情况 , 也就是 \(-1,0,1\)\(1\) , 而其中有一个特例 \(x=2\) , 因为此时 \(B\) 不能对 \(x\) 取两次 , 即 \(1\) 个的情况不能达到 . 也就是说总共的 \(n\mod 3 =0\)\((n-1)\mod3=0\)\(A\) 可以通过调整取 \(0\) 还是 \(1\) 来获得必胜 .

    这样最复杂的有 \(2\) 个的情况就显然了.

  • 有多于两个非 \(1\) 数 , 刚才分析的过程发现在 \(B\) 决定进入全 \(1\) 情况时 , \(B\) 是占相当优势的 . 考虑由 \(3\) 个转入上一种情况时 , \(B\) 在取完一个后是可以调整 \(1\) 的个数的 . 简单手模后发现 \(B\) 的这种调整足够强 , 使得这种情况下 B 必胜 .

总而言之并非不可做 , 从最简单情况一点点来推理 , 还是比较简单的 .

总结

首先考场上出博弈确实概率小一些 , 所以平时做的时候还是应该确定性地推理为主 , 不过确实不应该忽视一些实用的打表猜测的技巧 .

考场上如果真的遇到这种单一结论的题 , 到没有什么推进空间时应该打表观察 , 没必要硬着头皮推啊 .

T2(树链维护)

题意

一棵树每个点上有字符 \(c\) , \(q\) 次询问从 \(u\)\(v\) 的链上有多少子序列 , 等于 \(S(|S|\le30)\) .

题解

点分治做法

首先考虑用矩阵描述子序列 .

对于链查询 , 不只有树链剖分 , 因为矩阵的 \(m^3\) 过大了 , 而一时又想不出合理的方式 , 那就尝试先保留矩阵 , 发现单点的矩阵足够简单 , 可以 \(n^2\) 与另一个任意矩阵相乘 . 这放在树链刨分上显然没有用 , 但是还有其他更好的能利用这个性质的维护方式 : 点分治 .

然后一切都简单了 , 直接遍历子树 , 用 \(n^2\) 的这种性质暴力跑 , 复杂度等价于 \(n\log^3n\) .

题解做法

从另一个解决角度出发 , 子序列能否用其他更加简单的东西描述 . 回到 lca 上, 我们需要一种办法快速得知两条链与 \(S[1,i]\)\(S[i,n]\) 等价的计数 . 最简单的维护方式是差分 , 而这真的具有某种可减性 .

具体说 , 假设需要到根的链内任意一段 $x,y $ 内 \(S[1,i]\) 的数量, 如果想用 \([x,rt]\)\([y,rt]\) 的信息维护 , 发现这符合容斥的思路 : 从\([x,rt]\)\(S[1,i]\) 去掉 \(i\) 不在 \(y\) 以内的贡献 , 于是就可以考察在 \([x,y]\) 贡献 \([1,j]\) , 在 \([y,rt]\) 贡献 \([j+1,i]\) 的这种不合法的情况 .

复杂度等价于 \(n\log^2 n\)

总结

事实上 , 题解做法足够巧妙 , 但是确实需要想到用容斥处理这样一个看似不可差分的信息 .

更加重要的是前一种做法 , \(m^2\) 的单点矩乘易于想到 , 这时理应想到点分治利用这个性质 , 这就是一种基本功 .

那么在算法理解 , 和基本的应用经验具备之后 , 这种基本功应该体现为运用好算法 , 应对性质联系到做法的能力 .

至于如何训练这种基本功 , 或许就是继找性质的过程后 , 有意识地联系算法 .

总而言之就是主动地做题 , 而非被动受题目和题解的限制 .

T3(分治)

题意

把序列分成若干段 , 每一段的 \(2^{a_{i}}\) 之和仅有一个二进制位 . 求方案数 .

\(n=3\times10^5\) .

题解

\(DP\) 的角度 , 发现更新位置没有好的办法维护 . 发现这和笛卡尔树等思路有相似之处 , 发现一个区间内的最大值是不平凡的 , 可以考虑分治 .

考虑确定当前最大值 \(m\) 为分治中心 , 这一区间可行的最高位只有 \(log\) 种 . 此时用当前位置区可以断开左右区间 , 然后枚举 \(log\) 种情况确定当前位置的可行位置 .

但是此时不保证分治深度 , 在这种情况下优先考虑能否对原来做法简单修改达到正确 . 在这里 , 考虑启发式分裂 , 只枚举较短一侧 , 另一部分用预处理 .

这样找出了所有合法区间 , 数量并不多 , 就可以DP了 .

总结

整体而言考验思维连续性以及对分治的理解 . 是一道好题 .

需要用一些 启发式 的东西来思考 , 通过不断优化就可以达成正解 .

T4(分块)

题意

\(n\) 个任务 \(k\) 个机器 , \(q\) 次单点修改每个任务的时间 , 求最小等待时间之和 .

题解

这个问题需要转化 , 发现相当差分数组 , 于一个机器上系数逐一为 $1 , 2 ,3 \cdots $ 贪心地把较大的向小系数上填 .

所以相当于把原来序列 sort 后排在 \(1\cdots 1 2 \cdots 2 3 \cdots 3\) 下面求上下一一相乘之和 .

比较显然的根号分治是对 \(k\) , 把同一系数视作一层 , 如果 \(k\ge \sqrt n\) 可以直接暴力向下跳层 . 如果 \(k\le \sqrt n\) , 发现每次受影响是 \(\mod k\) 下一条链 . 两者都可以用平衡树维护 .

为了得到纯根号算法 , 可以考虑分块 , 把所有任务离线下来排序分块 , 这样把平移元素变成了平移下标 , 可以块内预处理解决 .

总结

根号分治是容易发现的 , 因此这道题拿到纯根号之前的大量分数还是没有问题 , 只是没时间写了 .

分块做法运用了一些转化 . 不管怎么说 , 根号在当下出题人卡常卡空间会被骂的情况, 确实不算常见的东西 , 重要的是做到有这个意识以防万一 .

总结

模拟赛总结

被 T2 车翻了 , 然后保守了一些没有冲 T4 , 去收集部分分了 .

充分说明读题的重要性 . 顺便单一性质题打表观察 .


基本功

最近又被提醒想到的一个关注点 . 等有一些体会了再详细写 .

posted @ 2024-12-17 21:39  youlv  阅读(20)  评论(0编辑  收藏  举报