跳转至

Record

2025 年 8 月(及以前)做题记录

可能会不定时放一些远古时代的题目。

[NOI2005] 月下柠檬树

平面几何,自适应辛普森法求面积,预处理圆的公切线,求值时单点取 max。

复习一下 simpson 公式 \(\dfrac {r-l} 6 (f(l)+f(r)+4f(\dfrac {l+r} 2))\)

注意如果超时可以去除层数的限制。

[HAOI2015] 数组游戏

博弈论翻棋子游戏 + 整除分块,感觉还是挺结论的。可能考场上打表或者认真思考也可以发现。

Hard Life

网络流最大权闭合子图模板,参考的这篇题解

[PA 2022] Mędrcy

好像是随机跳到的?

考虑从 corner case 开始到一般,这种每个人都绝顶聪明的推理要从每个人的视角考虑是否出现矛盾,即假设自己没有不知道的咒语,看他人的反应和基本公理是否冲突,可推断自己的状态。

最后得出结论求最小点覆盖,由于点数 \(k \le 30\),可用 \(T(n) = T(n-1) + T(n-3)\) 的最小点覆盖做到可以接受的复杂度(朴素做法 \(\mathrm{O}(2^k)\)),参考

有空补一下 CF164D。

【UR #6】懒癌

感觉还是比较抽象的,首先考虑一个人什么时候开枪,由于每个人都知道整个有向图,所以每个人可以从自己的狗没病的情况出发,在符合自己所见的情况中枚举所有可能状态,取最大值后+1即为开枪时间。转移成环的话都不开枪(相当于每个人都在等别人开枪)。

然后这个转化就抽象了,我们首先建一个有向图,图中边 \(u \to v\) 存在当且仅当 \(u\) 看不见 \(v\),然后考虑一个病的状态 \(s\),将有向图上的 \(s\) 中的点染黑,发现每次选择一个人转移相当于枚举 \(u \in s\),然后将 \(u\) 染白,将 \(u\) 的出边的一个子集染黑,求最大操作次数(做一次+1)。因为我们对有病的狗的主人的开枪时间取 min,所以每次只选除自己外可达前驱中没有黑点的黑点染白(不然的话选前驱会更小,前驱会再次染黑这个点,避免冗余操作)。显然黑点越多操作次数不降,而且转移成环相当于有向图中的一个环不停转圈,所以考虑缩点。如果一个强连通分量由至少 2 个点缩成,即存在环,那么这个强连通分量内以及它的前驱都不能染黑,否则没人开枪。然后考虑剩余点中染黑一个子集,发现策略是能染黑就染黑,且每个点只会染白一次,于是所有初始黑点的可达后继求个并集,大小就是开枪时间。

那么开枪人数呢?发现一个状态中开枪人数是取到 min 值的位置数,而为了取到 min 值,上面有提到只选除自己外前驱中没有黑点的黑点,计数是显然的。

用 bitset 优化求可达点集做到 \(\mathrm{O}(\dfrac {n^3} \omega)\)

【UR #19】前进四

Segment Beats。

可以兔队线段树做到 2log,不足以通过。

考虑离线,对序列进行扫描线,维护时间轴。每次扫到一个数,它在时间轴上呈现若干个区间,且这些区间总个数是 \(\mathrm{O}(n+q)\) 的。操作时对区间取 min 并记录有效取 min 次数,可以 Segment Beats \(\mathrm{O}((n+q)\log n)\) 解决。

有空补 线段树 3

[NOI2018] 情报中心

赛时没有认真思考,感觉看完题解好像没什么难点。

关键在于想到将贡献分拆在 lca 上,然后是带权直径的板子,可能会有一点细节。正解是分讨,会复杂许多。

[NordicOI 2022] 能源网格 Power Grid

想着数论做法,一边 assert 一边拍验证结论,大脑直接放空,导致获得 0 分。

还是要独立思考,发现自己在无脑猜结论时出去洗把脸。

主要是思路错了,一直 dfs 导致极其低效,做了 1h 后就应该反思或者放弃,正解思路有一点重合,感觉还是没有 bfs 式想题。

[ROI 2024] 无人机比赛 (Day 2)

被低年级选手单调队列 /ll

重点在于发现前缀严格最大值只有 \(\mathrm O(\sqrt n)\) 且只有这些位置有意义。然后拆贡献得到几个 \(\sum\) 后再根号平衡下就可以得到 \(\mathrm O(n \sqrt n)\) 的做法。

错误之一是没想到是根号,一直想 log 的部分分。然后是没拆贡献,感觉还是 trick 没有把握好。

[WC2016] 挑战NPC

一般图最大匹配,感觉还是挺考思维的。

AGC005E Sugigma: The Showdown

AGC 还是太吃思维了,什么时候可以战胜 /yiw

关键在于注意到如果一条边在另一树上两点距离大于 2 会 inf,于是只考虑距离为 1,2 的边。

又发现在对手的树上一定会深度递增(以对手起点为根),于是对手会不停向当前点走,即策略可定,dfs 找最优解即可。

P8864 「KDOI-03」序列变换

第一次被决策单调性打败,深刻认识到自己什么都不会。

赛时写了一个复杂 DP,没有想到更简单的形式,可能是后续优化没能进行的原因。

关键在于简单地刻画相邻两个不同位置最多 \(k\) 个,发现可以刻画成最多 \(\lfloor \dfrac k 2 \rfloor\) 连续的 1 段,奇数时特殊处理下。

于是用 \(w_{l,r}\) 表示所有的 \([l,r]\) 中的 1 移动到一起的花费,因为一定取中位数为中心最优,可以 \(\mathrm O(n^2)\) 预处理。

然后发现转移是 \(k\)\((\min,+)\) 矩阵乘法,于是快速幂做到 \(\mathrm O(n^3 \log k)\),运用神秘的决策单调性可以做到 \(\mathrm O(n^2 \log k)\)

[JOISC 2024 Day2] 棋盘游戏

可能看到 \(5 \times 10 ^ 4\) 已经不知所措了,赛场上打了 17 分还挂了。

关键在于想到其他 \(k-1\) 个棋子有两种决策,就是在两个棋子之间跳或者围着一个棋子跳,所以 \(1\) 号点每多经过一个停止单元格就会增加至少 \(k-1\) 的贡献,所以最多多经过 \(\lfloor \dfrac n {k-1} \rfloor\) 个。于是有 \(\mathrm O(\dfrac {n^2} k)\) 的做法。

然后发现 \(k\) 很小的话可以枚举斜率去切凸包,跑 dij 可以做到 \(\mathrm O(nk \log n)\)

平衡下可以做到 \(\mathrm O(n \sqrt{n \log n})\)

细节有点多,考察了 01bfs 和 dij。主要难点在于想到一个点对答案贡献是斜率为 1 或 2 的函数,然后想到两种做法后平衡。

P13497 【MX-X14-T7】墓碑密码

FWT 计数题,主要是想到用 FWT 推式子,然后用 __int128 和 popcount 加速计算 \(\sum_{j \in S} (-1)^{|i\cap j|}\),可能推式子需要一定的熟练度不然会推错或者做不出来,最后预处理组合数就好了。

还是有一定难度的,有空补 利物浦集合

[POI 2023/2024 R1] Satelity

\(n + \lceil \log_2 n \rceil\) 是显然的,然后就懵逼了。

发现原来可以这么推:设左边 \(s_l\),右边 \(s_r\) 个等价类(不失一般性设 \(s_l \le s_r\)),设左边最大等价类有 \(c_l\),右边有 \(c_r\) 个,那么花费是 \(s_l + \lceil \log_2 c_l \rceil + \lceil \log_2 c_r \rceil\),容易发现 \(s_l \le n - c_l + 1\)\(s_r \le n - c_r + 1\),又 \(s_l \le s_r\),设 \(x = \max (c_l,c_r)\),花费不会超过 \(n-x+1+2\lceil \log_2 x \rceil\),这个东西超过 \(n+1\)\(x=3\)\(x=5\) 的 corner case,特判即可。

还是比较思维的,以后束手无策时可以考虑设一些量推一推说不定发现上界。

P11692 [Ynoi Hard Round 2025] 《十字神名的预言者》宏伟(色彩)

lxl 安利的可持久化平衡树题。

先考虑 \(r=n\) 的情况,发现相当于在值域上从某个区间复制而来,或者再重复几遍然后放到操作的定义域中,并且对其中一段异或上 \(a\),于是可以用可持久化平衡树维护。

考虑一般情况下会出现什么状况,可能会产生 \(r\) 以外的贡献导致答案出错。一般的想法是 pushdown 的时候记录下异或产生的位置并且不合并标记,但是空间可能爆炸。

这时候需要用到取模的性质,即一个数取模不超过 \(\mathrm O(\log V)\) 次,因为一次取模至少减半。然后考虑 tag 用一个特殊节点表示,即操作点,只有一个儿子,节点本身有异或的信息。从节点内分裂出的子树要重新打上 tag,合并时不对特殊节点进行分裂。

考虑这样做树高时多少,发现从平衡树上一个普通节点往下走后如果不是走到特殊节点那么 size 减半,否则因为取模发生 \(\log\) 次,所以特殊节点只经过 \(\log\) 个,总树高还是 \(\log\) 的。

这里用到了全局平衡思想,即把取模的 \(\log\) 与平衡树的 \(\log\) 相加而非相乘,得到更优的复杂度,类似于全局平衡二叉树从树剖处优化而来。

总时间复杂度 \(\mathrm O(n \log n)\),不卡常。

计数 DP 技巧

Cat Jumps

sort: 组合意义

将形如 \(\prod _{i=1} ^{n} (x+i)\),其中 \(x = \sum_i^n a_i\) 的式子转化为对每个点连一条出边 \(j\),权值为 \(c_i = a_j + [j \le i]\),所有方案中边权乘积之和。这是因为 \(\sum \prod_i^n c_i = \prod_i^n \sum c_i\),而一个 \(i\) 的所有方案中边权和恰为 \(i+\sum a\),故相等。

之后用各类容斥技巧,以及第一、二类斯特林数进行计数。

AtCoder 训练记录

先贴上本人主页

ABC347

\(\Delta=\color{red}{-24}\)

蓝名保卫战,极限 1600

C 题还是有些思维难度的,最后才做出来,但是不够简洁

E 题忘开 %lld 喜提罚时

D 题最难评,又 WA 又 RE,最后如果输出不符合条件就输出 -1 才过

F 题原题,但是不会(

赛后发现就是一个二维前缀和 + 二位前缀max,还是挺简单的

G 题不会

赛时打的太急了,罚时太多,速度也被拖慢了,同分的最高 performance 有 2000+,还是代码实现不够快和准

AGC066

\(\Delta=\color{red}{-21}\)

E 题原题,还抓了一个抄题解的

A 题还是挺水的,只是没想到从奇偶性的角度来想,题解给的是 \(O(N ^ 2 D)\) 的做法,但是有更优且更简单的做法 \(O(N ^ 2)\),但是没想到,还是考思维。

B 题有点愚人节,python 语言优势很大(自带高精度),用几个 \(5 ^ x\) 拼起来多随机几次就完了,难绷(

蓝名没了 /ll

ABC348

\(\Delta=\color{green}{114}\)

performance 2300+ 祭

0罚时切 A ~ F,让我又想起了那场似的 rating

F 题听说比较水,暴力 + O3 可过,但是我用 bitset \(O(\frac{N ^ 2 M}{\omega})\) 也过了(

G 题决策单调性优化板题,原题两道:here & here (但我不会)

upd on 2024.4.14 : G 题改出来了,应用单调性还是比较简单的,但是难在证明

ABC349

\(\Delta=\color{green}{67}\)

A ~ D 都比较顺畅,D 题盲猜 \(\text{lowbit}\) 喜提机房一血,E 题没开 long long 喜提一发罚时与机房一血

然后就坐着与 F & G 干瞪眼,F 先是用 cdq 尝试水分,后来将不是 \(M\) 因数的删掉了,还是不行

最后发现 \(M\) 最多有 \(13\) 个因数,直接 \(O(2^{13}N) \approx 1.638 \times 10^9\) 过了,AtCoder 神机

但是打得太急,F 题 7 发罚时,最后 4 发最离谱,一发没取模,一发取模太慢 TLE,一发将取模改成减法写错了,最后一发两处取模是 copy 的都错了,漏了一处没改(

\(\color{green}{525} \color{red}{(7)}\) !!

G 题直接并查集开水,快 T 了就 No,过了一半的数据点

实际上还可以开随机化,因为对于 \(\forall i\),有些连边是不需要的,有概率连到与目标解答案相同的状态,但比赛后才想到(

ABC350

\(\Delta=\color{red}{-6}\)

之前的总结写的太笼统了,更像是提要。刚好今天实在是打 emo 了,犯了很多离谱的错误,想写一篇个人直观的反思,从 ratingperformance 中跳出来,慢慢地审视整个过程。

A 题其实没有问题,可以直接A的,但是把 %03d 写成了 %02d 样例中也没有 ABC001,于是就挂了。

后来几道题一直很慌,越慌,越是想打快。越是快,就越出错。这很严重拖慢了整个切题的速度。C 题本来是没什么问题的,但是急着想过掉它,核心的代码几乎一半是错的,第一发直接罚时,这时心情也是很差了,很焦躁。后来逼迫自己冷静下来,又在草稿纸上画了几下,思路便逐渐清晰,于是便改对了。

到了赛点的后三题后,我其实刚刚松一口气,看到 E 题又自闭了,毕竟概率题上次就栽过,是ABC342F,这次又看到,心里一紧,只好先尝试 F 题。

F 题读完题后没多久就想到了 dfs,然而实现中还是有一些小错误,如 for 循环里更新 i 的话,它实际上还会 ++i/--i 一次,会跳过一个位置。好在没罚时。

切完 F 题后看了一下 G 题,一开始读错题了以为那个在线是假的,高高兴兴拿样例试水发现是错的。没办法,于是看 E 题,结果旁边的人 看我蓝名快没了 好心旁敲侧击,于是想到 DP,中途还有一个自己转移到自己的,想到了之前的一道题目 虽然我没改出来 ,于是移项解方程即可。

一开始 \(10^{18}\) 我认为计搜是过不了的,因此打得不够坚定,还有一个变量重名调了很久,实现不够稳和准。开始是想着拿去水分的,但是直接过了,而且时间也很充裕(7ms)。赛后看题解,计搜时间复杂度实际上是 \(O(\log^3 n)\),但是主要问题是不会证明,对自己没有信心,于是犹豫了很久。

到了最后的 G 题,此时还剩下 20 分钟,已经机房内有人切了 G 题。出于对 G 题的潜意识压力以及前面比赛的表现,我此时已经基本失去思考能力了,脑子一片嗡嗡的根本想不到正解,打了一个根本就没概率的随机化过了一半,最后遗憾收场。

机房内同年级的有 4 个人过了 G 题,其中 3 人都是水过的,还包括两个代码相似的人。第四个大佬用了 splay

到这里,你可能认为 G 题还是有点难度的。但是,实际上,这也是我在比赛中犯的最后一个,也是最大的一个错误。

读完 G 题,其实不难想到如果维护好了森林中的每棵树有确定的根(具体是哪个节点与答案无关),并且维护好了每个点在其所在连通块中的朝向这个根的父亲,那么求解答案是 \(O(1)\) 的。比赛时这个念头在我脑海里一闪而过,但是很快就被否决了——原因很简单,这个维护过程直观上看是非常不可行的。后来,我转而去想 bitset 时间换空间,但一无所获。

然而,这就是问题所在——用暴力维护这些信息实际上的时间复杂度是正确的!因为每次连边的两个点都是在不同的连通块中,做完这次操作以后它们就会被合并,因此如果我们遍历一遍较小的连通块,总时间复杂度是 \(O(n\log n)\)!因此,这道 G 题出乎意料地短,甚至比我的随机化代码还要少。


写在最后:这次 ABC 可以看到除了少部分人,大多数人都没有取得很理想,甚至可以说糟糕的成绩。比赛结束后,我听到有人在机房里咒骂自己、题目和出题人的。还有人为了 rating 而闷闷不乐,诸如此类。但是有一点他们都错了,我们打比赛不是为了 rating 去打,不是为了成绩去打。以我为例,这次比赛我的 delta-6,相对于之前 2200+performance,可谓是相当的差。但是,在这背后,是我被打乱的做题节奏,被扰乱的心态,是我过于激动的心情。这次比赛,暴露了我很多问题:代码实现不准不细心,读题不仔细,对时间复杂度的不敏感,对时间复杂度证明的不熟练,而这些,都为我提供了宝贵的经验,这远远不是几点 rating 所能给我的。之前还看到旁边的人比赛时一起讨论题目,其实也是十分不应该——如果人人都只在乎 rating 以至于无人在乎算法背后的玄妙,在乎它们的出处与归宿,那么 rating 早已失去它本来的意义了。希望各位在天涯海角的 OIer 都能保住自己的初心,守住心中的一寸净土,为了 OIACM,乃至 CS 的明天而砥砺前行。