凸性学习笔记

Slope Trick

有一些常见的手法:维护差分序列 \(f_{i} - f_{i-1}\);维护凸包上的连续段;维护拐点。

这里的 Slope Trick 比较广义,也包括维护不凸的序列的差分。

CF1534G A New Beginning

考虑一条折线,距离 \((m,n)\) 最近的点,一定是直线 \(x+y = m+n\) 与折线的交点。

因此可以将所有点按照 \(x+y\) 排序,每个点在扫到对应的折线上时统计贡献。

我们可以设计出来 \(f_{s,x}\),表示走到 \((x,s-y)\) 的最小花费。

转移有两种,一种是 \(f_x \larr f_x + |p-x|\),一种是 \(f_x \larr \min(f_{x-1},f_{x})\)

这个转移不好维护。发现 \(f\) 数组具有凸性。那么第二个操作相当于把凸包上斜率为 \(0\) 的段拉长,然后再把后面的段往后平移。

维护拐点。考虑开两个 pq,分别维护凸包上斜率为正、斜率为负的部分。第一个操作是插入两个拐点,第二个操作是平移,可以在第二个凸包上面整体打 tag 实现。

时间复杂度 \(O(n \log n)\)

P11598 [NOISG 2018 Finals] Safety

从前往后 \(dp\)。状态和转移是显然的,和上面一个题完全一样。写上一题的做法即可。

P3642 [APIO2016] 烟花表演

记录 \(f_{u,x}\) 表示 \(u\) 子树内,叶子深度全都为 \(x\) 的最小花费。

转移有两种:\(f_{u,x} += f_{v,x}\),以及 \(f_{u,x+k} \larr \min(f_{u,x} + |k-p|)\),其中 \(k \geq 0\)

第二种是 \((\min,+)\) 卷积,所以每个 \(f_{u,*}\) 数组都是凸的。

第一个操作是凸包相加,第二个操作是一个简单的闵和。

维护拐点。第二个操作相当于弹掉斜率超过 \(1\) 的段,然后拉长斜率为 \(-1\) 的一段;第一个操作只需要把拐点序列合并起来。

使用启发式合并或可并堆即可。

CF573E Bear and Bowling

考虑从前往后 \(dp\)\(f_i\) 表示选 \(i\) 个物品的最大权值。

这个不是凸的。但是根据一些神秘观察,\(\frac{f_{i+1} - f_i}{i}\) 是单调不增的。

也就是转移时,\(f_i\) 的一个前缀不选,剩余的选。

使用平衡树维护差分序列,转移可以先找到分界点,然后差分序列做一次插入、一次后缀加即可。


另一个做法:这个问题,贪心选物品是对的。也就是,每次不断选择对总价值贡献最大的物品,加入子序列。

贪心需要做后缀 \(w_i \larr w_i + a_i\),前缀 \(w_i \larr w_i + x\)。这个可以上 \(\rm KTT\) 直接做,\(O(n \log^{3} n)\)

不会的话,有一个分块维护凸包的 trick,分块,然后对每一个块建出来凸包,这样整块加横坐标就可以快速做了。\(O(n \sqrt n)\)

CF1787H Codeforces Scoreboard

跟上面那个一样。

posted @ 2026-08-31 15:45  _Bonely_Muffin  阅读(12)  评论(0)    收藏  举报