NOIWC2025 实录
Day 1
杂题选做
[ABC387G] Prime Circuit
原题链接:https://atcoder.jp/contests/abc387/tasks/abc387_g
简要题意:对于 \(n\) 个点、有标号、每个环长度均为奇质数的仙人掌计数。
考虑 Prüfer 序列的相关结论:一个 \(n\) 个点 \(m\) 条边的有标号无向图有 \(k\) 个连通块,需要添加 \((k-1)\) 条边使得整个图连通,令每个连通块大小为 \(s_i\),方案数为 \(n^{k-2}\cdot\prod\limits_{i=1}^k s_i\)。
结合一些有标号图的计数技巧:每次加入一个环,钦定结点 \(1\) 所在的环大小为 \(c(c=1\lor c\in\mathbb{P})\)(其中 \(\mathbb{P}\) 表示质数集)——令 \(f_i\) 为 \(i\) 个点时答案的系数和(即最终答案为 \(n^{-2}f_n\)),有转移 \(f_i=n\sum\limits_{c=1}^i[c=1\lor c\in\mathbb{P}]\cdot c\cdot\mathrm{C}_{i-1}^{c-1}\cdot\frac{(c-1)!}{2}\cdot f_{i-c}\)。暴力做时间复杂度为 \(O\left(\dfrac{n^2}{\ln n}\right)\)。
正解是多项式复合,但是考虑到 \(12\mathrm{s}\) 的时限,所以尝试直接做。将求和中的一些系数提到外面算,加法时使用 __int128 最后统一取模;实测可以在 \(11\mathrm{s}\) 内通过。
提交记录:Submission #61721116
[ABC282G] Similar Permutation
原题链接:https://atcoder.jp/contests/abc282/tasks/abc282_g
简要题意:长为 \(n\) 的排列 \(a\) 与 \(b\) 的相似度被定义为:满足 \((a_{i+1}-a_i)(b_{i+1}-b_i)>0(1\le i<n)\) 的 \(i\) 的数量。求有多少对 \(1\sim n\) 的排列相似度恰为 \(k\),答案对 \(P\) 取模。
考虑 AtCoder DP 经典 26 题中 Permutation 的套路,令 \(f_{i,s,a,b}\) 为考虑了前 \(i\) 个位置,当前相似度为 \(s\),第一个排列中填入的最后一个数在之前的数中排名为 \(a\)、第二个排列中填入的最后一个数在之前的数中排名为 \(b\) 的方案数;转移分四种情况讨论,暴力做时间复杂度是 \(O(n^5)\) 的、空间复杂度是 \(O(n^4)\) 的,无法通过;但是考虑到第一维可以滚动数组优化,而转移时可以使用二维前缀和优化,这样时间复杂度是 \(O(n^4)\) 的,空间复杂度是 \(O(n^3)\) 的。
提交记录:Submission #61751215
Day 2
浅谈非确定性算法 - 周康阳
[CF1764F] Kazaee
原题链接:https://codeforces.com/contest/1746/problem/F
考虑将每个值随机替换为 \(0/1\),只需查询区间内所有元素的和并判断其是否是 \(k\) 的倍数。
上面的方法正确率为 \(\frac{1}{k}\),多做几次即可保证正确性。修改过程可以用树状数组维护。
[NOI2013] 向量内积
原题链接:https://www.luogu.com.cn/problem/P1224
提供一种不一样的做法。\(n=2\) 直接 bitset 暴力做,对于 \(n=3\),考虑对于每种乘法分讨,\(1\times 2\) 与 \(2\times 1\) 可以用异或处理,于是也能压进 bitset。
但是这样时间复杂度还是太高了,于是随机一下,就比较难卡了。
周康阳原创题
简要题意:给定一个长度为 \(n(n\le 5\times 10^4)\) 的序列,值域为 \([0,2^{60})\),支持区间翻转,查询区间内选出一个子集使得该子集内元素异或和最大,操作次数 \(\le 5\times 10^4\)。
随机 \(\frac{n}{2}\) 个点置为 \(0\),每次查询区间异或和,做 \(100\) 次塞进线性基里求最大值。单次错误率为 \(\frac{1}{2}\),做 \(100\) 次错误率即为 \(2^{-100}\)。
【模板】一般图最大匹配
原题链接:https://www.luogu.com.cn/problem/P6113
好像是一种很牛的线性代数做法。OI-Wiki 链接
[CF1641D] Two Arrays
原题链接:https://codeforces.com/contest/1641/problem/D
将值域随机映射到 \([1,15]\) 中,之后跑高维前缀和。
Day 3
杂题选做
[EGOI2024] Team Coding
原题链接:https://www.luogu.com.cn/problem/P10846
数据范围提示我们进行根号分治。
选定一个阈值 \(B\)。对于使用人数 \(\le B\) 的编程语言(不妨认为出现了 \(c\) 次),枚举团队领导 \(u\),再暴力枚举其他使用该编程语言的人对应的结点,如果该结点本来不在 \(u\) 子树内并且 \(u\) 子树内对应深度有“空位”(即可以与其交换,并使答案增大的结点),那么对其进行一次操作,使其进入 \(u\) 的子树内。处理子树内空位数量可以对于每个深度预处理出所有的点的 dfs 序,子树查就变成了区间查,直接 lower_bound 就可以了。这一部分的时间复杂度为 \(O(c^2\log c)\)。
对于使用人数 \(>B\) 的编程语言,仍然考虑每个团队领导 \(u\),对于每个深度考虑,第一个答案(人数)即为“\(u\) 的子树内该深度的结点个数”与“整棵树中使用该编程语言且位于该深度的人数”的较小值,将它们求和即为总答案;第二个答案(操作次数)只需在第一个答案的基础上直接减去“\(u\) 子树内使用该编程语言且位于该深度的人数”。以上需要的所有信息可以直接在整棵树上借助 std::unordered_map 做启发式合并。这一部分的时间复杂度为 \(O(n\log n)\)。
取 \(B=\sqrt{n}\),总的时间复杂度为 \(O(n\sqrt{n}\log n)\)。
思维型题目选讲 - 郭羽冲
[IOI2019] 折线
原题链接:https://www.luogu.com.cn/problem/P7195
讲义中提到了直接构造的做法。一种比较直观的想法是:一圈一圈往里绕,但是如果有点在角上那么段数可能达到 \(2n\);如果 \(x_i=y_i=i\),则应当从左下开始依次经过每个点。将两种想法结合,维护三个序列 \(a,b,c\),依次对应绕圈,左上-右下、左下-右上。四步为一轮,依次选择当前 \(x\) 最小,\(y\) 最小,\(x\) 最大,\(y\) 最大的点。若某次选择点之后发现无法与上一个点衔接,则说明一个点在角上,可以将其放入 \(b\) 和 \(c\) 中,依次访问三个序列,总共需要 \((n+3)\) 条线段。
[3rd Ucup Stage 21] Diverge and Converge
原题链接:https://qoj.ac/contest/1872/problem/9881
选择在两棵树中度数之和最小的点 \(u\),所有点度数和为 \(4(n-1)\),因此 \(\deg_1(u)+\deg_2(u)\le 3\)。
若 \(u\) 在两棵树中均为叶子,则交换对应的边并删除 \(u\) 即可递归子问题。否则不妨设 \(\deg_1(u)=1\) 且 \(\deg_2(u)=2\),令 \((u,a)\in T_1\) 且 \((u,b),(u,c)\in T_2\),且 \(T_2\) 中 \((u,b)\) 在 \(u\to a\) 的简单路径上。在 \(T_1\) 与 \(T_2\) 中将 \(u\) 删除,并向 \(T_2\) 中加入边 \((b,c)\),递归子问题。在子问题的解决中,必有一步交换 \((b,c),(d,e)\),将这一步扩展为:交换 \((u,a),(u,b)\),交换 \((u,c),(d,e)\) 即可得到原问题的解。
直接暴力做,时间复杂度 \(O(n^2)\)。
Day 4
考试日。
Day 5
试题题解
更新一下昨天的试题题解。
T1 猫粮(catfood)
以下将优质猫粮记为 A,普通猫粮记为 B。
注意到只有 \(2n\) 个猫粮,而猫有 \(n\) 个,又因为每个猫至少要吃两个猫粮,所以每个猫正好会吃两个。就变成了匹配问题。
考虑 AB 先匹配,然后 AA 匹配(如果剩余的 A 有奇数个考虑补一个进去,以下不妨设 A 个数为偶数;如果 A 的个数为 \(2\),那么只要满足 \(a_1+a_2=m\) 即可;否则需要满足 \(m\bmod 2=0 \land \forall i,a_i=\frac{m}{2}\)),最后还要判 BB 是否能匹配(不判这个只有 \(95\) 分)。
T2 Nim 游戏(nim)
TBD。
T3 士兵(soldier)
考虑简单 DP,设 \(f_{i,j}\) 为考虑了前 \(i\) 个位置,该位置上有 \(j\) 次攻击的最大收益,直接暴力 \(O(nV)\) 转移可以拿 \(20\) 分。离散化一下(存储每个 \(a_i\) 和 \(a_i-1\))可以做到 \(O(n^2)\) 的 \(40\) 分。
发现每次转移只有一个关键点可能被大改(\(a_i\) 或者 \(a_i-1\)),其他都可以用区间加简单地解决。于是拍个线段树上去,\(O(n\log n)\) 直接过了。
Day 6
今天没有前去听课,因为教授的内容比较科技。
在寝室里研究一个难题,到晚上终于研究出来了。
杂题选做
[EGOI2022] Social Engineering
原题链接:https://www.luogu.com.cn/problem/P9319
尝试猜测 Maria 会赢的充分条件:令在原图中与结点 \(1\) 相邻的点为“关键点”,假设将结点 \(1\) 和与其相邻的所有点的边都删去,只需要存在一个连通块中包含奇数个关键点,这个时候 Maria 每次随便选一个还没选过的点挑战就能赢。
对于其他情况,可以证明我们一定能赢,所以上述条件是充要的。只需要将每个连通块内的关键点两两匹配,并对于每一对匹配的关键点 \((u_i,v_i)\) 都找出一条 \(u_i\) 到 \(v_i\) 的简单路径 \(p_i\),使得对于任意两条不同的路径 \(p_i,p_j\),都不存在一条边同时出现在它们之中。
当 Maria 问到一个关键点时(不妨设为 \(u_i\)),只需沿着 \(p_i\) 一路挑战到 \(v_i\),最后挑战结点 \(1\)。
考虑每个连通块,求出满足条件的匹配。求出该连通块的一棵生成树,在树上自底而上贪心匹配(能匹配就匹配);由于连通块内关键点个数为偶数,这样匹配是满足条件的。
说起来简单,但是这个东西巨难写。写了一个下午 + 一个晚上,闹麻了。

浙公网安备 33010602011771号