凸性学习笔记
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
跟上面那个一样。

浙公网安备 33010602011771号