[CSP-S 2024] 游记

[CSP-S 2024] 游记

Day 1

为什么没有 Day 0?哦,原来是 Ehun 其实差不多退役了,前一天还在上文化课嘻嘻。

好的,由于今年 sc 是在我的母校考试,有主场优势(尤其是出来之后才想起来是之前集训的那间机房),感觉灵感都多了很多(虽然今年确实简单就是了)。

前一天还是简单复习了一下的,虽然看的是图论,但是也不是完全没有帮助吧?

走进学校发现全是熟人老师的感觉!!!

直接到达考场,先试机,发现自己连 NOI Linux 的虚拟机都用不来了——关于一名 OI 选手不知道如何才能够在虚拟机上编译的这一件事。

今年的 CSP 感觉格外神奇哈,就是说呢,CCF 终于也算是愿意写个程序回收的网页了吗,都懒得喷了,中国计算机协会自己的网页烂成一坨屎。今年试题也是从那个回收网站上下载,怎么不算另一种形式的 OJ 呢?

下午两点半,开题,先看到 T1 好的,看到 T1 之后感觉就是纯粹的贪心,于是排序,然后看值域,发现 \leq 10^6 立马就开了个桶,然后直接从大到小扫描,看能不能直接消掉就可以了,看题 + 切掉这道题一共花费 10min。

然后根据去年 CSP 的经验,感觉应该是没办法 AC T1 以外的任何题目的,所以就先通读了 T2 T3 T4 的题面,感觉然后看到 T3 好像可以入手,决定先开 T3,主要是看起来很像 DP 而 T2 看起来很像 DS,然后写了个 DP 方程,再看一眼题目,发现自己看错题了,只能说是梅开二度(参考去年 CSP-S T4)。很糟糕啊,然后回去先开 T2,不得不说今年题其实出的比去年好,就是难度确实是递增的。

看到 T2 这种在一条线上的题目和监测点,不知道为什么想到了天天爱跑步??但是其实也没有那么难,一个明显的想法就是直接将这些车会超速的这段路程全部转化为线段,对于加速度等于零的车,如果开始不会超速,那他整条路上都不会超速,直接可以排除,如果开始超速了,那么从他一上路就会一直超速到离开这条路,那么这辆车可被检测的区间就可以用区间 [d_i,L] 来描述。有了这个基本的思路之后,就可以尝试将所有的车全部转化为线段了,对于加速度 a > 0 的车,我们根据物理学公式 v_t^2-v_0^2 = 2ax,就可以轻松求出他在全路程上的速度(为了避免精度问题,直接将速度平方),那么我们先判断他最终会不会超速,如果最终都不会超速,那么一定就不会做任何贡献,直接删除,如果最终不会超速,那么我们一定可以找到一个位置,该车在这个位置之前都没超速,且从这个位置开始超速,由于车的速度具有单调性,可以直接二分查找这个位置 P_i,那么该车就可以用区间 [P_i,L] 描述,对于 a < 0 的车辆同理,先判断其最开始是否超速,若没超速直接删除,否则可以找到一个位置 P_i 使得到这个位置时仍然超速,这个位置之后就没有超速了,不用考虑之后的情况,题目中说了 v<0 时直接视为离开道路,这样就不用考虑倒着开(虽然是倒着开也不是不可做),这样的车就可以用区间 [d_i,P_i] 描述。对于第一问,直接遍历每辆车,询问其区间内是否含有监测点即可,区间操作可以使用前缀和优化(然而某个蒟蒻对这个静态区间先写了线段树,后因常数过大又写了树状数组,愣是没有直接用前缀和,幸好这个题给的 \texttt{2s} 不然感觉有概率挂分,千万别挂啊!!!大样例用了 \texttt{1.3s},CCF 神机救我狗命!!!)。这样解决了第一问后,我们把对第一问做出了贡献的车先按右端点从小到大排序,相同右端点再按左端点从小到大排序,这样我们枚举每个线段,如果当前使用的最贴近右端的监测点并不在区间内,那么这个区间必须要单开一个监测点,找到其中最靠右的监测点即可,可以证明这样子做不更劣,统计一共使用的监测点数目 cnt。那么第二问的答案就是 m-cnt(但是其实这个好像可以用差分约束直接做,但是考场上没想到,而且其实差分约束的复杂度不是很严谨,毕竟用的 SPFA,不是标准的 O(nlogn),感觉不如直接贪心做)。

一个半小时切了 T2 之后去开 T3 了,说实话 T2 这东西是真的难调,但是确实没想到自己可以做出来 T2,感觉很满足了 T3 就没什么负担了。重看 T3 发现可以转换题意,把红蓝染色看成每次遇到一个数,将其任意放入一个栈中,若当前栈顶与该数相同,那么权值累加该数的值,否则权值不变,使权值最大化。那么就可以定义 Dp_{i,j} 为,当前已经放入了第 i 个数,另一个栈的栈顶是第 j 个数的时候权值的最大值。如果 j=i-1 说明,当前的第 i 个数与它的上一个数 i-1 被放在了不同的两个栈中作为栈顶,那么

Dpi,i1=maxj=1i2{Dpi1,j+Calc(i,j)}

其中 Calc(a,b) 定义为如果 a 号数与 b 号数相同则为 Value_a 否则为 0。那么该方程也就是说 i 号数放在第 j 号数的头上的最大权值。而对于其他情况,我们有

Dpi,j=Dpi1,j+Calc(i,i1)

这样子写出来时间复杂度是 O(n^2),可以通过一半的数据。

其实打到这里已经有 250 分了,原本准备去打 T4 暴力的,想想还是算了,不一定打的出来说实话,所以继续看 T3 怎么优化 Dp。

仔细观察 Dp 方程可以发现,我们现阶段的第一维 i 只能从 i-1 转移过来,所以我们可以直接舍弃这一维,将复杂度降低到 O(n)。我们注意到当转移进行到第 i 层时,对于 \forall j\leq i-2 ,都会受到 Calc(i,i-1) 的影响,也就是说,舍弃掉第一维之后,我们有

Dpj=Dpj+Calc(i,i1)   (ji2)

而对于 Dp_{i-1} 我们也有如下转移方程

Dpi1=maxj=1i2{Dpj+Calc(i,j)}

也就是说我们着重优化下面这个方程即可,对于上面这个方程,我们的优化思路是直接记录一个偏移量 det,因为是对所有的 Dp_j 做修改,我们只记录减去了偏移量之后的值即可,最后回答询问的时候再加上偏移量就是最终答案,而对于下面这个方程,我们可以将其分类讨论。对于任意符合 Value_j=Value_ij,我们选出其中的 \max\{Dp_j\} 加上 Value_i 作为备选项,然后对于其他的 j,我们直接选出最大的 Dp_j 即可,两者比对就可以更新 Dp_{i-1} 了,最终我们选泽所以 Dp 值中的最大者,实质上这里不用管混杂在其中的 Calc(i,j)\neq 0j,因为这样的 j 不会影响最终结果,也就是直接选择所有 j\leq i-2\max{Dp_j} 作为第二个备选项即可。

如何维护这个优化呢,我们可以考虑记录离当前数最近的配对数,每次更新一个 i-1,我们都同时更新他与前面所有相同的数中 Dp 值的最大值(记得维护偏移量),这样的话每次转移都是 O(1) 的。时间复杂度 O(n)

T2 和 T3 就这样水灵灵地切掉了,真是不可思议,做完 T3 只剩半个小时了,就玩了会 NOI Linux,走出考场的时候整个人心情都是愉快的,预估得分:100+100+100+0=300。感觉不错,但是无论如何,今年都会退役了 \哭哭。

posted @   Ehundategh  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
历史上的今天:
2023-10-27 [NOI2010] 超级钢琴 题解
2023-10-27 [NOIP 2013提高组]货车运输 题解
2023-10-27 [TJOI2013] 松鼠聚会 题解
点击右上角即可分享
微信分享提示