紫题实战训练全记录:从省选备战到算法竞赛能力提升的方法论
下午两点我关掉所有通知在在线评测系统里开了一套四题的紫题训练卷。2026年3月6日的这场模拟我给自己设定的时间是四个半小时目标不是满分而是在省选同难度下检验自己能拿多少确定性分数。这四个半小时里我经历了读题时的从容、做数据结构题时的顺遂、字符串题上的反复横跳、概率DP状态设计时的挣扎还有最后阶段不得不放弃满分幻想、转向部分分保底的务实决策。复盘之后我觉得这次紫题训练的过程比结果更有价值所以把它完整写下来。文章里既有我对紫题难度的拆解也有具体的选题策略、实战时间线、卡点破解方法以及训练后该怎么复盘的操作框架。如果你也在备战省选级别的算法竞赛或者正从蓝题往紫题过渡这篇文章应该能给你一些可以直接照用的思路。1. 为什么要定期做紫题实战从“刷题量”转向“能力锚点”很多选手刷题量不小但一到省选难度就崩问题往往出在常年在蓝题舒适区里打转。蓝题练的是单项技能你拿到题就知道大概要用线段树还是动态规划思路通常在读题后几分钟内成型。但紫题不一样它考的往往不是单一技能而是多个知识点之间的组合、取舍和容错。为什么定期做紫题实战因为它是衡量你是否具备省选能力的最直接锚点。1.1 蓝题与紫题的本质区别我用一个自己做题体感上的对比来说明。蓝题像单点技能测试题目告诉你考什么你只需要把对应算法写对。线段树区间加区间求和刷过模板的都能AC。紫题更像综合场景测试考点有时不止一个而且不同考点之间需要做取舍。你经常遇到的情况是“每个算法都会但不知道该把哪个放在主位”或者“想到了正解方向但实现复杂度爆表需要现场降级”。我见过不少同学刷题记录上写着“AC 500题”但一到紫题实战就手忙脚乱。原因很简单刷蓝题训练的是“会”紫题训练的是“选”。后者需要在有限时间里判断哪条路最值得走、哪个算法能在这个数据范围内稳定过、哪些分可以舍弃。这种判断力只能通过完整实战来练靠碎片化刷单题是练不出来的。1.2 固定训练日期解决的是“承诺问题”紫题训练不应该“有空就做”而应该像正式比赛一样定下日期和时长。我自己的经验是一旦把训练日期写进日历到点开题不打折扣训练质量会明显高于随机刷题。固定日期带来的紧张感是模拟赛场状态的必要条件。平时刷题你随时可以停下来查题解、看讨论但紫题实战的规则是自己定的开题后不看题解、不查资料、不切出去聊天到时间必须停。这种“强制性”训练的是你在压力下的决策能力。如果哪天算法思路断了你也只能在纸上画图硬推——正式比赛里的状态本来就是这样的。我安排紫题实战的频率是一周一次偶尔两次。太频繁会挤占专项刷题和基础巩固的时间太稀疏又会丢失手感。2. 紫题到底难在哪难度跃迁的结构化拆解说“紫题难”太空泛难在哪个环节才是关键。我按照解题流程把难度拆成三段信息提取、模型抽象、实现容错。每段都有蓝题和紫题的明显差异。2.1 信息提取阶段题面里藏着的条件容易被漏掉蓝题的信息提取通常是直给的n、m、k这些范围都放在明面上算法一眼能对上。紫题则喜欢把限制条件藏在“多次操作累计”这种描述里。比如一道题说“执行m次操作每次操作会影响后续所有操作”如果你只看单次操作的复杂度就可能把总复杂度算错一两个数量级。我这次训练的第四题就在这上面吃过亏前几组小数据全部通过一到大范围测试点就超时原因就是我没有在信息提取阶段意识到“分组累计”会导致转移复杂度变成O(n^2)。2.2 模型抽象阶段能不能从题目描述里跳出来这是紫题和蓝题拉开差距的核心。蓝题的抽象是显式的看到区间修改就知道是线段树看到最短路就知道是Dijkstra。紫题的抽象经常需要绕一步甚至两步。我这次训练的第二题就是典型题面在讲字符串集合的插入和前后缀查询表面上是字符串结构题但实际上可以用有序表维护字典序区间来定位前缀再用哈希表做后缀过滤。如果你被“字符串就必须用自动机”这种惯性思维绑住就很容易把自己绕进去。蓝题到紫题的模型抽象难度可以简单用下面这张表说明维度蓝题常见状态紫题常见状态算法提示题干隐含明显算法特征需要多步推理才能锁定算法考点数量通常1到2个核心考点可能2到4个考点交叉数据范围明确定义边界清晰限制分散需自行估算总复杂度解法取舍正解路径相对唯一多条路径需要比较实现成本和稳定性部分分设计少见通常直接考AC常见出题人会留“逃生通道”2.3 实现容错阶段数据范围逼着你做代码取舍紫题对实现能力的要求不仅是“写得出来”还包括“在时限和内存内能跑得动”。我这次训练里就遇到过这种状况哈希加字典树的思路逻辑上完全可行但每个插入串都要存一份哈希值节点数量一上来内存就吃不消最终只能换实现方案。蓝题阶段你可能不会太在意内存限额但紫题必须在一开始就算清楚空间复杂度。这不是代码能力问题是提前规划的意识问题。3. 训练场搭建与选题策略组出一套有营养的紫题卷紫题训练效果好不好题目构成占了七成。如果一套卷子里全是你擅长的题型训练完你会很爽但能力提升有限。要刻意给自己制造“不舒适”。3.1 题目从哪里来回忆考点后自己重构我不是直接照搬某个题库里的原题而是根据自己的薄弱环节把经典考点改造成抽象题面。这样既能练到想练的方向又能避开“见过原题、凭记忆做”的虚假AC。这次的四道题我分别覆盖了数据结构、字符串处理、概率DP和组合计数其中字符串和组合计数是我相对薄弱的部分。题目准备好了最好请一位水平更高的朋友帮忙把控难度。我当时就把卷子发过去确认了四道题的难度梯度第一题紫偏蓝第二题纯紫第三题紫偏蓝但状态设计有坑第四题紫偏黑。这样的梯度能保证前面有分拿、中间有坎过、后面有挑战。3.2 时间分配原则前30分钟读题后面按优先级打四个半小时的实战前30分钟我只做一件事把四道题全部读完并在题号旁边标注“预期得分率”和“投入时间上限”。比如我这次第一题预期AC投入上限90分钟第二题目标部分分冲刺AC上限80分钟第三题和第四题只求部分分每道题最多留70分钟。不要小看这个动作。很多选手拿到题就从T1开始闷头做结果T1做崩了后面三道题连读题时间都不够。全局读题的意义在于你心里有一条清晰的路线图知道哪些题必须拿哪些题可以放哪些题卡住了要果断止损。3.3 环境模拟的细节我自己的做法是把题面打印出来纸质题面加本地编辑器不开代码补全不开网络搜索。手机放到另一个房间训练期间一律不看消息。这看起来有点苛刻但正式赛场上能有的一切干扰训练时都要模拟到位。赛后统计这四个半小时里我只看了一次时间还是因为想确认距离结束还剩多久。4. 四个半小时的实战记录从读题到交卷的完整链路这一节我按真实时间线记录当天下午的推进过程包括中间踩的坑和做的决策。它比单纯列题解更有参考价值因为它展示了“思路是怎么从A改成B的”。4.1 前30分钟全局读题带来的战略优势13:30开题。我用22分钟读完了四道题并在纸上写下初步判断T1数据结构给定一个数组支持区间内排序和整体求和n和m都是1e5级别。第一反应是用平衡树维护有序区间但实现量偏大。标签数据结构预期AC。T2字符串动态插入字符串查询前缀为S且后缀为T的字符串数量。字符串总数2e4总长度5e5。一眼想到字典树加后缀哈希但内存可能吃紧。标签字符串处理预期部分分。T3概率DPm个位置每个位置可选若干类型同类型连续出现次数有限制给定概率矩阵求期望得分。状态设计有坑标签动态规划预期部分分。T4组合计数把n个权重值分组求所有分组的加权贡献和对M取模M不是质数。我立刻意识到逆元不可用转移优化受限。标签组合数学预期部分分。最后8分钟我把每道题的投入上限写在了题号旁边。这个动作带来的最大好处是当我在T1上卡了一段时间后内心非常清楚继续死磕的代价是什么。4.2 第一题有序区间维护与贡献总和顺利AC我最初想用平衡树维护每个有序区间排序时把区间拆出来再合并。写了几行后发现代码量涨得飞快平衡树旋转变换和懒标记叠在一起调试成本不可控。于是我停笔重新想了一道区间排序本质上改变的是区间内数值的排列顺序而查询目标是整个数组的总和——后者其实不受排列顺序影响只受“每个数最终落在哪个位置”的影响。所以问题可以转成“维护每个位置上最终的值”。我改为维护一棵支持区间提取的平衡树每个叶节点存原数组中的位置排序时按值域顺序重组叶子。实现上虽然还是平衡树但逻辑比一开始清晰很多。14:50左右主体代码完成20分钟调试后AC。这一题给我的经验是紫题里“一步到位的正解”不一定是最快路径。如果你发现自己需要边写边想才能继续说明抽象可能不够彻底值得停下来重新整理思路。4.3 第二题字符串前后缀查询从字典树切换到有序表哈希T2的题面很明确在线插入字符串、查询前缀为S且后缀为T的字符串数量。第一版方案是字典树加哈希字典树负责定位前缀哈希表负责校验后缀。逻辑上趁手但每个节点都要存哈希值内存经过优化仍然超标而且查询时要扫描某个子树最坏情况退化明显。挣扎了大约30分钟后我决定换路线。因为查询只看“字符串是否在某个字典序区间内”而所有插入串形成的是一个按字典序排列的集合。我改用一棵按字典序维护的平衡树每次插入一个串就更新节点查询时前缀为S的字符串在字典序上位于某个连续的区间内二分定位起点和终点即可后缀部分用辅助哈希表过滤。这个方案的优点是内存占用明显下降缺点是后缀过滤仍需遍历区间内每个串。由于总长度只有5e5在实测数据里表现尚可但大数据集下部分测试点超时。最终这题拿了3.8/5的部分分扣分点主要在极限规模的后缀过滤耗时。4.4 第三题概率DP的状态维度缺失与补丁第三题是我这次训练里复盘价值最高的一题。题面抽象后大概是这样m个位置每个位置可以选k种类型中的一种选了某种类型后如果上一轮也是同类型额外概率收益会衰减且同类型连续出现次数不能超过limit求期望总收益。我第一版状态定义是dp[i][j]表示前i个位置、第i个位置类型为j时的期望收益。转移时我卡住了如果当前类型j和上一轮相同我需要知道已经连续了多少次但dp[i][j]里没有这个信息。这时我停下来用“信息不可压缩原则”检查了一遍——如果省略连续次数两个不同的历史状态会撞在一起但未来行为不同说明状态确实缺维度。补丁方案是改成dp[i][j][c]c表示当前连续次数从1到limit。状态数量变成O(m乘以k乘以limit)k和limit都是10级别时勉强能跑。实际提交后部分测试点超时最终得分2.3/5但正确性明显提升。如果我在读题阶段就提前把“连续次数限制”列入边界清单应该能省掉那20分钟的返工。4.5 第四题组合计数与取模限制下的保底策略最后一道题只剩大约70分钟。题面要求对M取模而M不是质数这意味着很多常规的组合数化简都不能用逆元。我先写了最朴素的O(n^2)递推拿到2/5的部分分之后尝试用单调队列优化某一段转移但因为M的限制优化空间比想象中窄。最终止步于2/5。说实话第四题我在读题阶段就知道不可能满分所以心态反而平稳。拿到2/5后我把剩余时间用来检查前两题的边界情况修正了T2的一个排序比较器漏洞这部分检查直接防止了第二题从3.8/5跌回3/5。最后总得分13.1/20按真实省选的分数线看这个分数有机会过但不算稳作为训练来说达成了拿“确定性分数”的目标。5. 紫题训练中的典型卡点与破解方法如果你也做过紫题训练大概率遇到过下面某一个卡点。这里我把这次训练以及过往训练中整理的三类典型问题展开聊聊。5.1 知道算法却写不出来构建“带扩展点的模板”卡点表现算法知识都认识动手写就不断写错下标、漏判边界。“线段树我会写但为什么紫题一叠加自定义操作就崩”原因是你缺少一个高熟练度的个人模板。蓝题往往只需要套模板紫题则要求你在模板上做扩展——加一个操作、改一个合并逻辑。如果模板本身不熟练扩展点就是车祸现场。我的做法为每个高频算法维护一份“自定义模板”模板里明确标注扩展的位置。比如线段树节点结构体里用一个merge虚函数之后想改区间合并逻辑时只动这一个函数。DSU加按秩合并和持久化回溯也是类似的思路。平时专项刷题时先用自定义模板做两道旧题做冒烟测试确认模板没问题后再进紫题实战。5.2 状态定义差一个维度信息不可压缩自检法紫题的动态规划经常让人卡在状态定义上。你觉得自己定义的状态覆盖了所有情况但转移时发现还有信息没存只好回去加维度。杜绝这个问题我建议用“信息不可压缩原则”做自查如果从完整状态里拿掉某个信息后你无法仅用剩余信息判断下一步是否合法那这个信息就不能被压掉。写转移方程之前强迫自己回答三个问题每一步决策依赖哪些历史信息这些信息里有哪些会被未来决策再次用到如果省略某个信息会不会出现两种历史状态被压缩到一起但未来行为不同的情况第三问一旦答“会”就必须加维度。这次T3的连续次数限制就是典型的需要保留的维度。5.3 边界条件在最后一刻崩溃读题阶段建立边界清单边界条件问题是我过去踩得最频繁的坑尤其是n1、k0、limit0这类起始边界。现在的做法是读完一道题后先不急着想主算法而是把“数据范围边界”和“状态边界”列成一张清单。比如“n1时的初始化是什么”“排序区间为空时怎么办”“连续次数为0时状态是否合法”。这张清单在整个编码过程中都要对照。调试阶段不看题面而是看清单往往能更快定位错误。这次训练的T1如果没有提前处理长度为1的区间排序初始化代码里就会直接出数组越界T3如果不考虑limit1的情况转移写法甚至会打印负数。边界问题看似是小问题但在紫题里它经常决定部分分数量。卡点典型表现破解方法实现能力不足算法懂但代码写不出来维护个人化模板标注扩展点状态维度缺失转移时缺少关键历史信息用信息不可压缩原则做三问自查边界条件错漏大数据正常、边界数据崩溃读题阶段建立边界清单编码时逐条对照6. 训练后的复盘从“记录得分”到“发现模式”紫题实战的价值一半在场上一半在场后。复盘不是把题解看一遍然后感叹“原来如此”而是要找到自己的思维模式偏差。6.1 复盘四问找出“偏离正解的起点”我复盘的固定动作是四问这道题我第一反应是什么我是什么时候开始偏离最优路线的题解的哪一步是我没想到的这个“没想到”是知识缺失、经验不足还是状态问题拿T2举例我第一反应是字典树加哈希偏离发生在内存超限后没有尽早考虑有序表方案。题解用有序表维护前缀区间这一步我其实是能想到的但当时被“字符串题就该用字典树”的惯性思维绑住了。这个归因就属于“经验不足”而不是“知识缺失”。经验不足的解法是多做跨知识点的综合题让思维不再按题面表面结构选算法。6.2 错因分类与下一阶段计划这次四道题我给自己记了三笔账T2的贡献拆分慢属于“抽象模型选择保守”——题告诉我是字符串集合动态查询我就默认走字符串结构路线没有先考虑全局有序性带来的字典序区间性质。T3的状态维度缺失属于“信息保留不足”——没提前预判连续次数会影响未来转移。T4的内存与时间双超限属于“实现结构与数据范围匹配失误”——读题时我知道M不是质数但没第一时间意识到逆元不可用会压缩优化空间。这三类错误对应三个训练方向抽象建模需要多练跨类型综合题信息保留需要多复盘DP转移设计结构匹配需要养成读题即估算空间时间复杂度的习惯。下一步的专项计划我会把这两个星期的日常刷题重点放在“贡献拆解”和“状态设计”上各安排三到四个专题。6.3 紫题训练的频率、难度配比与长期收益紫题训练做多频繁合适我最终的经验是每周1到2次完整实战。间隔期用蓝题模拟保持手感和得分节奏同时集中刷一两个薄弱知识点专题。完整实战的核心意义是定期制造“紧张条件下的决策练习”频率太高会占用补短板的时间频率太低则丢失压力感。难度配比上不要每次都挑战紫偏黑。训练的核心是“可感知的进步”如果每道题都超出当前能力太多复盘反而会失去针对性。我这次的四题配比是1道紫偏蓝、2道纯紫、1道紫偏黑就属于一个比较合适的梯度。7. 一点私人体会把紫题训练当作“定位器”而非“对答案机”做了半年多的定期紫题训练我最深的体会是它最大的产出不是某一套卷子的分数而是无数个“过程数据”。你每次在哪个环节卡住、哪种题型的得分率稳定偏低、哪些边界条件反复出错这些数据组合起来就是一张清晰的能力边界地图。比分数更重要的是紫题训练教会我接受“不完美通关”。正式比赛里经常拿不到满分但你要在有限时间里拿到最大化的确定性分数。这个决策能力只能在模拟实战里反复练习。我在训练日志里专门留了一页记录“当天最有价值的一个战术决策”例如这次就记了一条T1卡住时果断停下重想抽象模型比硬着头皮写完香得多。如果你也打算安排一场紫题实战训练我的建议是题目宁缺毋滥四道一个下午正好不要只追求AC部分分的获取同样值得复盘不要省略读题阶段30分钟换来的全局路线图能救你无数次更不要跳过复盘分数告诉你结果复盘告诉你过程里哪里值得改。下次训练时希望我们都能少踩一个坑多拿一分确定性分数。