OI-wiki 🌟 当算法竞赛变成一本可以众筹的“游戏攻略” 🔥
想象一下这样的场景:深夜两点,你盯着一道题,感觉它认识你、你不认识它。你隐约记得某个东西叫“后缀自动机”,或者“扩展卢卡斯”,但具体怎么用、复杂度多少、边界条件是什么,全像被格式化了一样干净。这时候你会打开什么?
大多数人打开的,不是编译器,而是浏览器。而浏览器里那个被无数 OIer 和 ACMer 收藏的标签页,往往就是 OI-wiki。
今天(2026-10-17),OI-wiki/OI-wiki 出现在 GitHub Trending 中文区日榜上。它的项目描述非常诚实地自嘲了一把:🌟 Wiki of OI / ICPC for everyone.(某大型游戏线上攻略,内含炫酷算术魔法)。这句玩笑话说得挺到位——对圈外人来说,算法竞赛确实像一款门槛极高、术语满天飞的“大型游戏”;而对圈内人来说,这本 wiki 就是那本被翻烂了的攻略书。
先搞清楚:这是款什么“游戏” 🎮
OI(信息学奥林匹克)和 ICPC(国际大学生程序设计竞赛)本质上是同一类活动:给你一个精确描述的问题,在有限时间内设计出正确且足够快的算法,然后用代码把它实现出来。它的“装备”是各种数据结构,它的“技能树”是各类算法思想,它的“Boss 战”是那些卡常、卡精度、卡边界条件的毒瘤题。
这个领域有个特别尴尬的特点:知识密度极高,但知识极度分散。你学会一个算法,可能只是因为在某次集训里听人提了一句,或者在一篇排版混乱的博客里抄到了半份代码。下次再遇到,你只记得“好像有个东西能解决这个”,然后开始漫无目的地搜。OI-wiki 想解决的,就是这种“知识在不同人脑子里各存一份、互相不通”的碎片化状态。
这本攻略的“地图设计” 🗺️
一个合格的算法 wiki,难点不是“写多少”,而是“怎么组织”。因为算法知识天然是一张网,而不是一棵树——学动态规划要先懂递推,学斜率优化又要先懂动态规划;学网络流会牵扯到图论基础,学生成函数又会绕回组合数学。如果按严格的树形目录切分,读者很容易在某一层卡死。
从公开的项目定位来看,它覆盖的是竞赛选手实际会用到的那一大片区域,大致可以理解为这样一张技能表:
- 入门与基础:语言基础、复杂度分析、枚举与模拟、排序与二分——也就是“新手村任务”。
- 数据结构:栈、队列、堆、并查集、树状数组、线段树、平衡树、可持久化结构……从木剑一路升级到传说装备。
- 图论:最短路、最小生成树、拓扑排序、连通性、网络流、二分图匹配。
- 动态规划:线性、区间、树形、状压、数位,以及各种优化技巧。
- 数学:数论、组合计数、概率期望、线性代数、多项式与生成函数——也就是描述里那个“炫酷算术魔法”的正体。
- 字符串、计算几何、杂项技巧:那些平时用不上、一用上就能决定名次的东西。
这些条目真正的价值,不在于“有”,而在于彼此之间被链接起来了。你在读“树状数组”时,旁边可能就挂着“逆序对”和“二维偏序”的入口;你在读“扩展欧几里得”时,顺手就能跳到“同余方程”。对学习者来说,这种横向跳转比一条笔直的学习路径有用得多,因为真实的困惑从来不是线性的。
把知识当 API 查:一种“接口设计”思路 🔍
我特别喜欢把这类 wiki 当成一个“知识 API”来看待。它的好坏,可以用几个很工程化的指标来衡量:
- 可发现性:我能不能在几次点击内,从一个模糊的记忆(“那个能快速求区间最值的结构”)定位到准确条目?
- 可达性:条目内部有没有前置知识的指路?一个只学过基础语法的人,读“可持久化线段树”时会不会直接原地去世?
- 可验证性:结论、复杂度、正确性证明是否写清楚,而不是只给一份“能 AC 的代码”。
最后一点尤其关键。竞赛圈里从来不缺代码,缺的是解释代码为什么对的文字。一份只贴模板的博客,你抄完还是不会用;而一份讲清了“为什么这样合并”“为什么复杂度是这个量级”的文档,你下次就能自己推出来。这也是 wiki 这种形态比零散题解更适合长期沉淀的原因。
攻略里的一页长什么样 💻
拿竞赛里最经典的并查集举例,一篇合格的条目不会只丢一段代码就完事,它至少会交代:初始状态、路径压缩与按秩合并的区别、复杂度从哪来、以及什么场景该用带权并查集。代码本身大概会长这样:
struct DSU {
std::vector<int> fa;
explicit DSU(int n) : fa(n + 1) {
std::iota(fa.begin(), fa.end(), 0);
}
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]); // 路径压缩
}
bool merge(int a, int b) {
a = find(a), b = find(b);
if (a == b) return false; // 已在同一集合
fa[a] = b;
return true;
}
};
短短十几行,背后却牵着一串问题:为什么 find 里可以写赋值?递归会不会爆栈?不加路径压缩只做按秩合并且路径压缩,复杂度分别是什么?这些问题才是“会用”和“懂了”的分界线,而文档存在的意义,就是把这条线画出来。
为什么一本 wiki 能一直活着 🌱
算法知识有个残酷的现实:它会过时、会被人发现新写法、会被指出错误。任何靠少数几个人维护的技术文档,最终都会停在某个时间点上。而 wiki 形态的核心优势,就是把“纠错”变成了任何人都能参与的动作——发现一处笔误、一个边界没讨论清楚、一段代码在某个编译器上不过,都可以直接提改动,而不是在评论区里自说自话。
某种意义上,一个社区维护的知识库,最珍贵的资产不是内容本身,而是“有人愿意持续修正它”这件事。
对使用者来说,这带来一个很实际的建议:别只当读者。你读某一段时卡住的地方,大概率也是后来者会卡住的地方;你把那一句补上去,等于替未来的一百个人省下了半小时。学算法最难的是“从会做到会讲”,而写文档恰好就是逼自己完成这一步的训练。
给不同阶段读者的使用姿势 📖
- 纯新手:别从头啃目录,按“能做出题”的顺序走——先语法与复杂度,再排序二分,然后最短路和基础 DP。wiki 是参考书,不是连续剧。
- 准备比赛的人:把 wiki 当查询工具,遇到陌生名词立刻查,顺手把跳出来的相关条目也扫一眼,这比刷十道同类题更能扩展武器库。
- 已经开始写题解的人:反过来用它校对——你以为你懂的东西,去对照一下准确的定义和复杂度,经常会有惊喜(惊吓)。
回到那个自嘲式的描述:一款大型游戏的线上攻略,内含炫酷算术魔法。确实挺酷的——它把成千上万人踩过的坑、推过的式子、写错的边界,压缩成了一片可以被搜索、被链接、被修改的文字。今天它出现在 Trending 上,本质上是一群人用行动给“开放知识”投了一票。
下次半夜三点再遇到那道题时,希望你打开的不只是搜索框,而是这本还在被人不断写下去的游戏攻略。🌟