2024.2.22 梦想 在什么地方 总是那么令人向往
字符串太难了。
今天早上起来牙又疼了,很难受。
UOJ461
考虑当前已经把整张图分成了 \(L,R\) 两个点集,考虑 extend 一个点进来。
可以使用二分的方式,具体的将未加入的点按任意顺序排列,二分一个前缀并断掉 \(L,R\) 与这个前缀的所有边,找到一个最小的前缀满足此时不连通,此时对于这个点可以认为它可以被 extend 进点集。
判断这个点在哪一边是容易的,依靠这个也可以判二分图。
于是做到 \(O(n\log n+2n)\) 次。
https://uoj.ac/submission/679581
CF1534G
欲使 \(\max(|X-x|,|Y-y|)\) 最小,则有 \(|X-x|=|Y-y|\),那么意味着我们的 \((X,Y)\) 一定会是 \((a,x+y-a)\)。
将所有点按 \(x+y\) 排序,于是我们一定会向右或者向右上走,于是可以列出 DP,令 \(f_{i,x}\) 表示在 \((x,x_i+y_i-x)\) 这个位置取 \((x_i,y_i)\) 的最小代价:
\[f_{i,x}=|x-x_i|+\min_{x'\in[x-(x_i+y_i)+(x_{i-1}+y_{i-1}),x]}f_{i-1,x'}
\]
此时 \(f_{i}(x)\) 可以认为是一个下凸函数。考虑这些操作在下凸函数上的操作,即 slope trick。
- \(\min\) 操作:可以认为是拉伸最小值段,相当于对右侧的所有斜率变化点添加一个定值。
- \(+|x-x_i|\) 操作:讨论这个位置是在左侧还是右侧,可以认为是添加一个斜率变化点。
于是使用堆维护左右两侧的斜率变化点,对于 \(\min\) 操作可以为 \(R\) 打懒标记,加绝对值可以认为是插入两个 \(a_i\),左侧的最大值需要弹到右侧或者右侧弹到左侧,可以维护,\(O(n\log n)\)。
https://codeforces.com/contest/1534/submission/247760096