省流
\(20min\) 拿下四题,自信跳过看起来复杂的 E 去做数据结构 F,结果迷失在调线段树未能通过。
10.4
内含剧透,请vp后再来。
不是题解!!!!!!!
赛前
白天一天什么也没做,就写了一篇前一天 \(CF\) 的题解,幸好有一把 \(ABC\) 不然又是毫无意义的一天。
赛时
A 题把字符串对应成相应的数字比较大小即可,不提。
B 题给定一个字符串,要求找到一个只出现一次的字符,剩下的字符均为同一个字符。我是直接拿第一个去比较所有的剩下的,如果找到一个和第一个相同的就直接输出第二个,否则输出第一个。做完 C 后发现挂了,原因是第二个可能也是与第一个相同的,所以还要再遍历一边找到与第一个不同的字符,在 \(12min\) 以一发罚时通过。
改 B 之前没等测试结果直接看的 C,C 题有一些操作,每个操作要求把所有小于等于 \(x\) 的数变成一个大于 \(x\) 的数 \(y\),然后输出这个操作变了多少个。数据在 \(1e6\) 的范围。发现我们每次变化之后小于等于 \(x\) 的数都没了,所以记录一下现在到哪里没数了,下面的就不用再遍历。也就是说每个桶最多被遇到一次,复杂度就是 \(O(n)\),\(11min\) 通过。
D 题给了一个 \(01\) 串,每次操作可以把头或者尾的一个字符反转然后插到字符串的任意位置,问至少多少次操作能把这个串的数字变得全部相同。看一下样例可以发现除了选定的最中心的那个串之外别的字符都要动,和最终不同的只用动一次,而相同的要动两次。那么去找最长的 \(0\) 串和 \(1\) 串并统计 \(0\) 和 \(1\) 的个数就可以解决了,\(20min\) 通过。
然后看了一眼 E 题,发现又是式子又是距离的,很烦,看了一下榜发现 E 和 F 过的人差不多(实际上只是因为我前面写的勉强可以算有一点快 E 和 F 过的人数还没分层)就去先看了 F,发现是数据结构爱好者最爱好的数据结构,于是直接扑上去写 F。
F 是在一个线段树范围里执行操作,把一个区间里的数都减少 \(k\),如果不足 \(k\) 的就减到 \(0\)。发现又是 \(log\) 数据又是区间减直接往线段树想,考虑怎么维护不足 \(k\) 的。发现如果有一个数减到 \(0\) 之后特殊判断一次,之后就不用管他,这样每个数都最多被特殊搞一次,时间复杂度就还是 \(O(nlogn)\) 的。那么就维护区间中除了 \(0\) 之外的最小值,如果小于 \(k\) 就往下去特殊搞掉他。再维护一个不为 \(0\) 的数量就可以快速计算出后面区间减该返回的东西。这种显然写一个正常的懒标记线段树就很好搞,但是我擅长写不下传标记的线段树,于是决定和他搏斗,对于某个当前点他的最小值靠下面更新上来,上面的则看累计的标记,本身则看需要的那个 \(k\)。终于,最后还是在不知道哪的细节挂了。
赛后
稍微改了一会 F 没对,去看题解发现我的思路是完全正确的,重构一下代码应该是可以过的。但是在用 \(AI\) 帮我查代码的时候(我确实懒了,对不起,真的查不出啊)看到了吉司机线段树,决定去学习一下。吉司机线段树主要实现了一个新的功能就是把一些点的值和 \(x\) 取 \(min\) 或者 \(max\)。应用到这道题目,就是直接减 \(k\) 之后再和 \(0\) 取 \(max\) 就可以了。实现思路其实和我们刚刚想的思路很有相似之处,线段树中额外统计最小值,次小值和最小值的个数,以及把子节点最小值都改成了 \(x\) 的懒标记。如果 \(x\) 小于最小值那么无事发生,如果 \(x\) 小于次小值,那么把最小值改成 \(x\) 并记录一下下传的时候应该把下面的最小值都改成 \(x\),然后剩下的就按正常的来下传标记之类的就可以,\(sum\) 的变化则可以利用 \(min\) 和 \(x\) 之差,以及最小值的个数求出。如果 \(x\) 大于等于次小值,那么就递归下去全部更新一遍,但是由于至少最小值和次小值都会变成同一个数,所以这个操作最多做 \(n\) 次所有数就都一样了(在有区间加之前),均摊下来的复杂度仍旧是 \(O(nlogn)\)。
然后看了 E 题,题目给了两个人在点上,然后他们都有一个目标,都以每秒一个单位的速度向目标走去,走到目的地之后就停下来,问过程中最短距离是多少。前一天打的时候简说就是个三分,我随便感觉了一下挺对的直接写交上去挂了,然后研究一下,发现一个人停下来之后模型就不对了。两个人一起在走的时候,可以视作一个人没动,另一个人相对他做匀速直线运动,那么显然距离是二次函数。但一个人停下后,另一个人的速度和方向就变了,可能就不对劲。所以要分停下来之前和停下来之后两种情况三分,然后就过了。
这场比赛给的分数换算成 \(cf\) 之后表现分是 \(1736\),说实话并不好,我很难愿意承认失败的原因是先开了后面的题目,我认为更大的问题是我强行写了不下传标记的线段树嘴硬而不是写更好实现细节更少的正常线段树,这确实是一个问题,先开数据结构的策略问题不大(当然就结果来说肯定还是先看 E 好,但有的时候 E 推式子就是比 F 线段树花时间)。还有一个问题是现在数据结构的东西越补越多,变成数据结构爱好者了,我还要加强别的方面才行。
2025年10月5日