陈昕阳IOI2025参赛总结IOI2025参赛总结2025-09-20 09:25:51
非常荣幸能够代表中国参加在玻利维亚举办的第37届国际信息学奥林匹克竞赛(IOI2025)。玻利维亚路途遥远,苏克雷城地处三千米高原,气候也较为恶劣,感谢正副领队罗老师、林老师以及观察员韩老师、杨老师在旅途中给与我们的帮助和照顾。
虽然 IOI 的比赛环节非常重要,但对我而言,非比赛时与其他选手的交流留下了更多愉快的经历。因此在这篇文章中,我将从非比赛和比赛两个方面总结此次 IOI 的经历。
对我而言,这次 IOI 去程就并不顺利。由于玻利维亚几乎在中国的正对面,去程需要乘两趟 12 小时的飞机。而也许是因为飞机上的空调制冷效果过好,在第一趟飞行途中我的膝盖和小腿越来越感到疼痛,而止痛药不幸被托运了。等到下飞机时我几乎不能走路,所幸吃了止痛药之后这种症状基本缓解。然而落地后我又不幸发现,也许又是空调的问题,我还感冒了。
虽然有这些不顺,但到达苏克雷后我们还是遇到了许多十分友善的选手与非选手。我们先遇到了来自 OpenAI 的人员,他们作为比赛的 sponsor 来到 IOI。其中一个人向我们说他是 IOI1999 中国代表队的一员,后来还发现他其实是韩老师的同学。我们的 guide 叫 Bri,她很友善,在接下来的几天对我们的生活也非常负责。在最后几天我看到她带着 IMO2024 的帽子,但由于我在 Day2 的失败我完全无心向她询问此事,实在有些遗憾。现在想来她在闭幕式时说她对我们的成绩感到非常开心,其实也许有着比我当时所体会到的更深的含义。我们还很早遇到了澳大利亚队和加拿大队。澳大利亚队基本都是华裔,有两个人中文说得很好。我向他们开玩笑说虽然我是中国队 CF rating 最高的选手,但我并非水平最高的选手,他们回答说他们队也是。接下来他们主动问我们会不会玩三国杀,但虽然我的队友范斯喆和刘海峰是这个游戏的高手,我和刘恒熙却几乎不会玩这个游戏。但令人惊讶的是,澳大利亚队竟然全员都会玩三国杀,而那盒三国杀是中文的。他们解释说,用 google translate 可以很好地理解规则,我感觉很神奇。加拿大队的 Ryan Bai 同样中文很好,他向我们展示了几个用扑克牌的魔术。观战几局后我也学会了三国杀的规则,接下来几天我们经常和澳大利亚队的选手和 Ryan Bai 以及其他一些不固定的选手一起玩三国杀,非常欢乐。到闭幕式时我们关系拉近了很多,并一同拍了合照。
住宿条件是八人间。我们的室友是多美尼加共和国代表队,这是来自加勒比地区的一个岛国,不过或许大多数人对它的印象是这是海地的邻国。他们算法竞赛水平不高,但人都很友善。他们中的一位选手经常在我们玩三国杀时围观,不过他好像到最后也没搞清楚规则。
开幕式的早上是试机赛,进场前我们同韩国队、日本队以及中国台湾队、中国澳门队的选手都愉快地进行了交流。韩国选手对我们说他们做了我们今年 CTS 的题目,并认为都非常困难。我认同了这一观点,并向他们解释事实上 CTS 有一半题目无人通过。我们还向日本选手解释了中国国家队选拔的流程,他们表示这非常复杂而漫长。中国台湾队选手向我们分享他们选拔代表队的流程,并表示最后一场比赛只公开题面而不公开数据和标程,并且他们怎么想也不知道如何在给定的限制下通过题目,怀疑也许标程根本不存在,数据是用暴力跑的,我感到十分趣味。中国澳门队的选手我们在此前就认识,也向他们打了招呼。我们还尝试和日本队以及中国台湾队交流一家著名日本公司发行的游戏,遗憾的是他们都对此一无所知,似乎这些游戏事实上在中国知名度最高。试机赛开始后我使用自己带过去的键盘轻松愉快地完成了试机赛的题目,并不知道其实存在一个潜藏的问题。
开幕式在苏克雷市中心的一个图书馆内进行。然而这个图书馆是露天的,坐在被太阳直射的地方会感到很炎热,而坐在不在太阳直射的地方则会感到很冷,苏克雷恶劣的气候由此可见。开幕式有很多南美特色的表演,虽然也许是因为文化差异,对于一些节目我感到莫名其妙。玻利维亚的现任总统也出现在了开幕式并用西班牙语和英语进行了发言,可见主办国对此次活动的重视。开幕式较靠后的环节是依次让所有代表队起立致意,其他许多代表队都在这个环节中展示了他们的国旗,然而尴尬的是我们发现我们忘记带国旗了,以后的选手建议记得带上国旗。
开幕式的晚上,罗老师给我发微信说我的键盘有无线功能因此被 reject 了。我非常惊讶也有些惊慌,因为我的键盘是别人送我的,并且它看上去并不像有无线连接功能,但我确实没有仔细检查。主办方准备的键盘是西班牙式的,键位和国内通行的有很大差异,如果现在改用主办方的键盘势必会很不适应,并且试机赛也已经过去了。最后罗老师说可以明天帮我寻找一下可用的键盘,我怀揣着不安陷入了梦乡。
开幕式的下一天是 city tour,但早晨起来我发现外面非常冷而我有些感冒,再想到键盘的事,我完全无心参加 city tour,于是我向 Bri 请假。中午杨老师在苏克雷的 central market 找到了两块可用的键盘,一块是美式的,键位与国内通行的相同;一块是英式的,键位与国内通行的区别在于其有两行 enter。我一开始回复说买美式的就可以了,然而杨老师认为 IOI 也就参加这一次了不差这点钱,将两块键盘都买了回来。然而当我等待一段时间后真正试用键盘时,却发现那块美式键盘其实是坏的——一些按键会随机失效,而且重新插线失效的按键会变化,幸好那块英式键盘似乎没有问题。我心有余悸,并对玻利维亚的商品质量有了新的认识。Day1 前一晚我吃了安眠药,但仍然在 3 点醒来,尝试入睡后睡到 5 点实在睡不着了去上了个厕所。但我上厕所后我的三个队友也都轮流起来上了厕所——原来他们都已经醒了。
在两天比赛的间隔我们去了苏克雷附近的一个城堡参观,城堡是非常西式的,据说是一个欧洲人到玻利维亚所建,可以算是非常不错的景点,不过事实上和我小时候去欧洲旅游时看到的城堡几乎完全一致。参观结束后还组织了一些游戏,但我认为感冒后在高原上不宜多运动就没有参加。回程我坐在车上一个窗玻璃漏风的位置,向车内灌的冷风让我感到很冷,直射的阳光又让我感到很热,这种矛盾让我感到很难受。
接下来是比赛的经历,不过比赛前的准备应该也算是比赛的一环,因此我先介绍一下我为 IOI 在训练方面所做的准备。
一方面我参加了在各个选手学校举办的国家队集训以及 NOI2025,在各个选手学校举行的集训包含模拟赛和国家队队员之间进行的好题分享,在这些训练中我增长了一些水平。但令人遗憾的是无论是模拟赛还是好题分享都一定程度上存在选中的题目与 IOI 考察方向不甚相符的问题,部分题目对 IOI 而言其实并无训练价值。希望未来在举办这些活动时能选择一些更契合 IOI 风格的题目。
另一方面我在时庆钰学长搭建的 QOJ 上自己训练了 IOI2015~IOI2024 的题目(QOJ 上现在可以提交 IOI2002~IOI2025 的所有题目,也推荐以后准备参加 IOI 的选手在这上面训练) 。感受是早年 IOI(例如 IOI2023 之前)的题目都比较简单,基本上没有我不会做的;但 IOI2023 和 IOI2024 的一些题目比较困难,我可能只会一些部分分。考虑到肯定是 IOI2023 和 IOI2024 的题目更具参考价值,我认为应该做好有题目不会做的心理预期,不能太追求 AK。同时我发现 IOI 题目的部分分一般都会提示正解,所以我决定不会做整道题时多去思考子任务的解法。
除此之外,我还阅读了往届 IOI 参赛选手所写的参赛总结,并发现以往成绩不理想的选手大多是因为时间分配不合理,一直在困难的题目上卡着导致没做简单题,或者是因为花费了太多时间实现错误算法,于是我告诉自己赛时要着重注意这两个问题。
接下来是 Day1 的过程。我进场阅读三个题,souvenirs 是构造题,部分分表比较奇怪;triple peaks 前半部分是比较传统的数据结构题,我应该比较擅长,后半部分是提交答案,不过倒是顺带指出了答案的量级不会太大;world map 是构造题,2 的比值感觉还是比较紧的。
我先尝试解决 world map。虽然题面里写了保证有解,但很容易发现给出的图不连通时无解,那么不难猜测剩下情况都有解。有一个子任务是图是一棵树,我发现按顺序考虑每条对角线,将每条对角线都染成同一颜色后构造树的欧拉序即可解决这个子任务。推广到一般的情况,可以对一些对角线进行 “扩充” 从而构造额外的边。我发现这个做法需要约 4n 条对角线,但 k/n 为 4 时只能拿到 72 分。接下来我思考了一会对这个做法的优化,但没有什么进展。我还尝试了一些其他的方向,然而这些方向似乎非常不靠谱,甚至不能得到一个正确的做法。在 35min 时我认为不宜再想下去,但比赛只进行了这么短的时间写暴力也不合理,于是换到了 triple peaks。
进行一些简单的分析,我发现虽然题面写的条件比较泛化,但本质难以统计的情况只有一种。进行一些代数推导并观察构造部分对答案的量级的要求大约是 n^1.5 级别后我意识到这应该是一道根号分治的题目(这在 IOI 倒是相对少见),分别写出两个在等价类大小较大以及等价类大小较小情况下执行的代码后我在 1:13:12 通过了 triple peaks 的第一部分获得 70 分。
此时因为 world map 我认为我已经会 72 分做法,我决定思考 souvenirs。我先尝试不看子任务直接思考无特殊限制的做法,然而想了一会感到非常迷惑,完全看不出可能的做法。于是我开始思考子任务,我很快想出了 n=3 的做法并发现询问某个之前询问得到的数除以某个数的商是非常必要的操作。但我接着思考有着其他特殊性质的的子任务 3,5 时却感到毫无头绪,更令我迷惑的是子任务 5 的分值非常高有 28 分,我理解为这个子任务的做法对整个问题的做法比较关键。又思考了一段时间后我得到了子任务 3 的做法,但在子任务 5 上仍然毫无进展。最后我放弃思考这个子任务而尝试思考无特殊限制的做法。经过一些尝试后我发现维护一个阶梯形的结构其实就可以直接解决原问题,而子任务 3 的做法与无特殊限制的做法似乎并无联系,子任务 5 的特殊性质对我想出的做法也并无简化,我对子任务设计感到莫名其妙,并在 2:18:14 通过了 souvenirs。
此时我认为 world map 我会 72 分做法,但 100 分做法也许与 72 分做法并没有什么联系,因此如果先实现 72 分做法而后来会了 100 分做法,可能 72 分做法的代码会白写。而 triples 后半部分同样有 30 分可得,且这个部分分值较少可能难度较为简单,也许一些不会 triple peaks 前半部分的选手都可以解决后半部分的构造。于是我决定快速完成 triple peaks 的构造部分再来思考 world map 的 100 分做法,如果完成 triple peaks 构造部分后时间已经较少,就直接写 world map 的 72 分做法。
考虑到 triple peaks 前半部分的做法,我至少需要构造使得有 sqrt(n) 个大小是 sqrt(n) 级别的等价类才有可能让构造出的答案是 n^1.5 量级。然而与我对构造部分难度较低的估计不符的是,我一开始尝试的几个简单构造最终都失败了,只能让答案达到 O(n) 量级。等我终于找到正确的构造并写对代码,时间已经来到了 3:29:21。并且我在提交后还惊讶地发现,我的构造由于构造出的答案虽然是 n^1.5 量级,但实际上常数并不优秀。而 n 限制较小的测试点的 k/(m^1.5) 比值反倒比 n 限制较大的测试点更大,因此我的构造能通过后几个测试点而只能在前几个测试点得部分分。简而言之,在构造部分我只得到了 24.43 分。
由于花费了比预期更多的时间,我有些烦躁。考虑到之前决定打得更稳健一些,我决定先写一份 world map 72 分做法再考虑进一步优化。在 3:58:00 我调对了代码却意外地发现这份代码获得了 100 分。仔细想想,我发现我的做法需要约 4n 条对角线,但大小为 k 的矩形本身就有 2k-1 条对角线,所以我认为 k/n 为 4 的做法实际 k/n 为 2。我感到有些幽默,并意识到今天可能可以 AK 比赛。
既然我 triple peaks 构造部分的代码量级已经正确,而只是常数不够优秀,我的第一反应当然是试着优化这个构造的常数。但我一开始尝试了一些优化方向,却发现这些方向实际都并不可行。换个角度想想,我的构造通过了所有 n 较大的测试点,于是写另一份代码对构造进行爬山/退火可能也能通过 n 较小的测试点从而通过题目。于是我实现了一份简单的退火代码,并在第一个测试点得到了一个 4.83 分的解。但接下来继续调整参数却都得不到更优秀的解了,而这个退火在第二个测试点就已经不如构造代码给出的解。在比赛结束前夕,我尝试了一些其他优化构造代码的方向,并多通过了一个 n 较大的测试点。最后我在构造部分得分为 4.83+4.18+5+5+5+5,Day1 总得分为 100+99.01+100=299.01,出场看到 Day1 排 rk2,我的队友刘恒熙 AK 了是 rk1。
出场后我得知 triple peaks 构造部分如果使用更高明的退火的交换策略,可以通过前两个测试点,从而拼上我的构造部分代码就可以通过这道题目从而 AK。刘恒熙找到了看待 triple peaks 问题的一种更优秀的角度从而直接得到了更好的构造方式,但既然我已经有一个前半部分的做法,也很难想到这个更优秀的角度。Day1 的成绩令人满意但略带遗憾。
接下来是 Day2 的过程。festival 像是先 exchange argument 确定操作顺序然后再如何优化一下 DP,也许是所谓的反悔贪心,但我并不擅长这种东西;migrations Z<=4,M<=8 的满分限制看上去非常紧,应该是得部分分比较容易但难以通过的题目;obstacles 和 NOIP2023 T3 比较类似,也许可以用类似的方法解决。
我先尝试解决 festival,并发现确实可以用 exchange argument 确定出最优操作顺序,在 0:33:28 提交了正确的 n^2 DP 代码获得 22 分。但接下来我尝试对这个 DP 进行优化却很不顺利,尝试了一些常见的方法都不奏效。我也想到过去掉所有被偏序的决策,但第一个子任务即可让这个做法的时间复杂度退化回 n^2 因此我没有实现这个做法。接下来我发现题面写了一个很奇怪的限制 t[i]<=4 并开始思考是否关键其实在于这个限制,正解会是关于 4 指数的,但这方面的尝试也没有任何结果。在大约 1h 时我放弃这道题转而去思考 obstacles。
NOIP2023 T3 我所了解的做法是,只需判断是否可以画出一个完全障碍物构成,符合某几种固定结构的框能否隔绝起点和终点即可判断起点和终点是否实际上连通。我猜测 obstacles 一题也有着一样的结论,只需要改一下框的结构。然而由于开场就在 festival 受挫,根据我的经验如果再在 obstacles 写一个假做法可能整场会直接崩盘,于是我不敢太过激进。obstacles 的部分分设计也比较令人迷惑,甚至没有 n,m,q 都很小的子任务帮助我确认我的结论的正确性。在一段时间的 struggle 之后我从调整对偶路径形式的角度证明了我的结论,但还是不放心于是写了一份用这个结论暴力判断的代码和直接按题意模拟的代码对拍。对拍显示确实是对的,于是我开始考虑如何利用这个结论解决这个问题,然而四个自由度的询问仍然让我感到非常迷惑。又枚举了一会做法后我终于发现对于一种较为复杂的框的结构可以找出 O(m) 个支配点对而有 83 分的 l=0,r=m-1 的子任务只需要判这种框结构,于是我尝试实现这一做法。然而似乎一切事情都非常不顺,最终我在对拍的帮助下才在 2:12:34 获得 83 分。
接下来我开始思考 migrations,我很快意识到可以将传信息的过程分为若干段,每一段内专门传上一段要发送的信息,然而这样最后一段的信息必须专门特判,我花费了很多时间才理清楚这个特判具体要如何处理。在明确各个部分到底要怎么写之后我没有过多考虑,直接开始写计算出最优的 Z=4,M=15 的做法。然而这个做法远比我所预期的难以实现,写了一会之后我发现事情不对劲于是对几个部分使用了更劣的实现,然而还是写了 6K 代码。写/调这份代码的过程中,我意识到如果这份代码调不出来或者做法有问题今天的比赛就彻底崩盘了,甚至可能真的要拿银牌,于是非常紧张和焦虑,几次感到无法再写/调下去,但最终都重新说服自己做法一定是对的,时间还足够。写这题代码的过程中我的鼠标还坏了两次,它会突然变得只能移动但不能点击(于是实际上没有任何用,或者说只有滚轮能用),我无法打开任何文件或是用鼠标切换现在所编辑的代码行号。我举手示意设备故障,然而工作人员两次都花费了大约 5min 才为我更换新的鼠标。而 IOI 的规则是 10min 内解决的故障不予加时,我甚至怀疑理论上坏 10 次鼠标每次 10min 内解决不给加时也是符合规则的。3:57:17 我提交了在本地通过对拍的代码,然后发现我的代码获得了 0 分,返回的 verdict 是 execution killed(一般而言是因为 RE 或者 MLE)。
我感到头昏脑胀,甚至一下子没想起 execution killed 到底是否可能代表 TLE(事实上这会显示为 execution timed out)。随后我检查是否是因为本地交互库与实际不同造成的差异,然而即使我改成 run twice 的形式(即真的按照题目所描述的方式改交互库)似乎仍然能在本地通过随机数据。我 Day2 的比赛全程心态就没有好过,而这几分钟是我最崩溃的时刻。我完全不知所措,开始随机修改一些看上去可能带来问题的地方。所幸 4:13:18 奇迹发生了,虽然不知道为什么,突然就能得分了,我得到了 75.34 分。直至现在写参赛总结的时刻,我也不知道这究竟是为什么,不过也没有知道的意愿了。
现在的得分是 22+75.34+83,并且将会的分全部写完是 66+86.4+83。此时的两种选择是把所有会的部分分写完和思考 festival 正解。由于先前的种种不顺我非常心烦意乱,我认为我在最初 1h 状态较好时也做不出 festival,现在由于时间短缺也更加没有可能。于是剩下的时间我将所有会的分拼完以 66+86.4+83 结束了比赛。结束时我苦中作乐:Day1 的金牌线是 231.50,而我 Day2 的分数确实超过 232.49 ,于是总之是拿到金牌了。
出场后我看榜 Day2 单天排 rk17,果然很不理想,总榜由于 Day1 的优势排在 rk5。我的三名队友都很快通过了 festival,他们和我说只需要特判所有 t[i]=1 之后不被偏序的决策就只有至多 O(log V) 个,所以一开始被我所否决的思路其实是正确的。我感到这题其实很简单,没有通过它是一个很大的失误。migrations 可以写得更简单(主要是在最后一个段的特判上可以简化),我花费 2h 获得 75.34 的速度太慢了。obstacles 我的做法其实很容易优化到 100 分,去掉 l=0,r=m-1 的限制会需要多判一种框的形态,但这种框的形态反倒比我所解决的那种更容易处理,但由于我在剩下两道题上花费了太多时间(以及在这道题上太过犹豫),我根本没有去思考这种框如何处理。
Day2 我的表现无疑并不令人满意,我想需要找出一些理由以给接下来的选手予以警示。先从做题角度来说,如果什么题都一下就能做出来那么许多问题也就不存在了。我无法快速解决 festival 我认为一方面是受到了题目中无意义限制 t[i]<=4 的误导,我错以为 IOI 的题目一般题目的限制或是部分分一定都不是随意给的,而一定有着提示正解的作用,然而 Day1 的 souvenirs 和 Day2 的 festival 都证明这不是真的。当然这并不意味着思考 IOI 题目的部分分对正解就一定毫无帮助,一些有帮助的例子是 IOI2017 的 wiring 的子任务 3 以及 IOI2024 的 sphinx 的 partial score,这两者都对正解有很大的帮助。IOI 的命题也并不是十全十美,设计对正解毫无帮助而只是给选手一些得分机会的子任务也是有可能的。另一方面我还是受国内常出的题目的影响太深,我所训练过的题目中与 festival 类似的需要优化状态数为 O(n^2) 的最优化 DP 的题目要么做法是数据结构维护 DP 数组,要么就是 slope trick,导致我赛场上也侧重于这两种思路,但其实都不可行。IOI 的题目还是具有一定创新性,风格也与国内比赛有差别,思考时还是不要太被常见思路束缚。migrations 似乎并不只有我表现不佳——以得到超过 70 分为目标,刘恒熙花费了 1.5h,范斯喆花费了 2.5h,我花费了 2h,而刘海峰则花费了 1.5h 左右没有想出超过 70 分的做法(虽然他似乎会 65 分做法但由于策略失误没有实现这个做法),这样的成绩实在不能说对外国选手有较大的优势。我认为这题展现出了中国选手普遍对通信题,特别是 run twice 形式的通信题不熟悉,缺乏训练,希望以后的选手引以为戒。我在解 obstacles 上的表现尚可,没有通过这题主要是受其他题以及策略上的拖累。
接下来从策略角度来说。我首先做出的抉择是只会 festival 的部分分没有选择立刻去拼这个部分分而是先去做其他题,虽然调 migrations 时 festival 只有 22 分也对我的心态造成了一些影响,这我认为不算一个大的失误。接下来我在 obstacles 表现得非常谨慎,不敢贸然相信画框的结论是对的,甚至到想到证明之后还是写了对拍确认的地步。这个抉择是否正确我认为要按照对比赛的期望分类讨论:如果目标是夺冠,那这当然没有必要,太浪费时间了;但如果目标是要稳拿金牌,那稳健一点也确实没错。随后我直接写了 migrations 我所想出的最复杂难以实现的 Z=4,M=15 的做法,这个决策是错误的。因为实际上 Z=4,M<=50 就可以得到 70 分,而 Z=4,M=15 也只能得到 86.4 分,分差非常小。而 Z=4,M<=50 代码可以写得很简单,节约很多时间。甚至于我在想出 migrations Z=4,M \le 50 的做法后再思考都是错误的,如果我想出 Z=4,M<=50 做法后就直接写, 可能 1h 内就能得到 70 分,就可以多出很多时间做剩下的题目,可能比赛的结果就被改写了。最后我放弃思考 festival 正解而是拼暴力,这个抉择和 obstacles 写对拍确认结论差不多,取决于你对比赛的预期来决定对不对。
于是我认为,我 Day2 的失败更多地是因为做题策略上的失误以及对 run twice 通信题缺乏训练,也存在一些比赛策略不合理的因素。不过因为每个题都做得不顺积累起来导致比赛崩盘的情况是我备赛 IOI 时完全没有预料到的,也许我的准备还是欠充分。无论如何,希望此后的选手能注意到更多的比赛中可能出现的问题。
那么,属于我的 IOI 的故事虽然带着遗憾但也终究是落下帷幕了,希望以后的选手能在 IOI 取得更好的成绩。