模拟赛

记录人生的第一场 AK

开 A,题目描述很吓人,但是随便胡了一发猜的结论,拿了 \(48\) 分,发现是数组开小了,开大,AC了。

开 B,想了一会,发现可以二分搞过去,具体来说就是开值域个 vector,每个vector记录这个数出现的下标,然后挨个判断。
笑点解析:\(O(n)\) 的算法会 MLE,我的不会。

开 C,像是个 dp,题目描述比 A 还吓人,于是去开 D。

D 我好像读错题了,但是好像又是题目写错了,总之就是阴差阳错地认为只能选一个元素,然后分析了一下,把整个过程分为了从前往后换和从后往前换,然后发现变化量容易用李超线段树维护,于是就做完了,交了一发就过了,此时还剩 2h。

只剩 C,去厕所寻找一下灵感, 回来还是不会,就颓了半个小时,然后开始分析。

先把 \(d\) 数组前缀和预处理一下。

首先容易发现这要么是个 \(O(pn)\) 要么是个 \(O(pm)\)。往 \(O(pn)\) 方面想,想不到,于是往 \(O(pm)\) 方面。

设第 \(i\) 个人走到第 \(j\) 只猫的最小花费是 \(f_{i,j}\),推了一会发现没法转移,于是继续想。

发现可以把这么一个东西抽象成平面直角坐标系的东西:第 \(i\) 只猫的坐标是 \((d_{h_i},t_i)\),然后每个人从 \(t_0\) 出发走一遍就相当于一条 \(y=x+t_0\) 的直线,这条直线下面的猫就都能被拿走。

然后把猫按 \(t_i-d_{h_i}\) 升序排序,此时就没了后效性,考虑转移。

\[f_{i,j}=\min\{f_{i-1,l}+\sum_{p=l+1}^r ((t_{h_r}-s_r)+d_{h_p}-t_p) \} \]

为什么呢?因为一个结论:排好序之后,把第 \(r\) 个猫拿走的直线是过 \((d_{h_r},t_r)\) 这个点的,很好证明。

现在暴力转移是肯定远远过不了的,考虑优化。

首先可以滚掉一维,先搞了再说。

\[f_i=\min\{g_j+\sum_{p=j+1}^i((t_{h_i}-s_i)+d_{h_p}-t_p)\} \]

前缀和维护一下:

\[md_i=\sum_{j=1}^i d_{c_j} , mt_i=\sum_{j=1}^i t_{c_j} \]

\[f_i=\min\{g_j+(i-j)(t_{h_i}-s_i)+md_i-md_j-mt_i+mt_j\} \]

\(\min\) 去掉,拆开:

\[f_i=g_j+it_{h_i}-is_i-jt_{h_i}+js_i+md_i-md_j-mt_i+mt_j \]

发现是一个斜率优化,做一下变形。

\[g_j+js_i-md_j=s_ij+f_i+is_i-md_i+mt_i \]

\[Y(j)=g_j+js_i-md_j,X(j)=j,K(i)=s_i \]

直接单调队列维护下凸壳即可。

posted @ 2024-03-21 17:39  Linge_Zzzz  阅读(12)  评论(0)    收藏  举报  来源