test20260728
text202607283
\(\text{P4427}\)
树上差分简单
\(\text{P1514}\)
结论:在有解的前提下,对于第一排的蓄水池能流到的最后一排的城市一定是一条连续的区间
证明:
如果不是连续的区间,那么中间有一个断点。因为有解,所以这个断点,可以被其他的点给流到。为什么会出现断点?这个蓄水池流下去的时候出现分叉,而有因为有别的线段能流到这个断点,所以别的蓄水池就会与这个分叉有交点,其实这个蓄水池直接沿着这条路径流下去,就不会存在断点.
这样就可以通过记忆化搜索,找到每一个蓄水池的能流到的最靠左的最后一排城市
问题转化为,选择最少的区间数,覆盖整个最后一排
线段覆盖,按左端点排序,贪心找最大右端点
\(\text{P1155}\)
第一步,划分限制,二分图染色
观察题目,发现一个序列来的时候,你直接排序时用上了另一个栈,说明某些元素不能放在同一个栈
那么可以找出这个限制,即哪两个元素不能放在同一个栈
发现当存在 \(a_k < a_i < a_j (i < j < k)\) 时,\(i,j\) 不能放在同一个栈
首先当 \(a_i > a_j\) 时肯定是可以放在同一个栈的,直接把 \(j\) 丢到 \(i\) 上面
而当 \(a_i < a_j\) 时,因为 \(i\) 要先出栈,所以\(i\)会尝试在进栈之后立刻出栈,不要被 \(j\) 压在下面
而为什么有的情况会让\(i\)无法提前出栈,导致 \(i,j\)不得不分到两个栈里?因为还有的数要在\(a_i\) 前出栈,也就是 \(a_i\) 此刻还不能出栈
这样,可以把\((i,j)\)连边变成图,那么要判断这个图是否为二分图,如果是那么就有解,如果不是,那么就无解(表示存在\(i,j\)无法把他们分开,而他们有必须分开)
第二步,直接出入栈
接下来的步骤是顺序扫过整个序列,把这个元素丢到二分图染色时他的颜色所对应的栈
重复执行,只要现在有元素可以出栈,那么就马上让这个元素出栈(可以出栈也就是这个元素是场上还未出栈的元素的最小值)
第三步,贪心微调
发现如果只是按照第二步这样做的时候,操作序列不一定是最小的
发现当满足有相邻两个操作,在交换他们的顺序不影响得到正确排序,且交换这两个元素可以使字典序更小时,那么就可以交换这两个操作(一个栈出栈和另一个栈入栈互不影响)
这样排序类似冒泡排序,排\(n\)轮就一定能得到最优答案了
小细节
二分图染色究竟染成什么颜色丢什么栈?
即两个颜色与两个栈有必须的对应关系吗?
交换这个对应关系影响得到正确答案吗?
其实栈与颜色的对应关系是不能交换的,不论我们第三步的关系怎么补救,缩小操作字典序,那也只能改变操作的先后顺序,不能改变某个元素进某个栈的结果
什么样的对应关系才能得到正确答案呢?
当你把点染成 \(0/1\) 两种颜色且代码如下时
fore(i, 1, n) {
if(c[i] == -1) dfs(i, 0);
}
你一定需要把染成了颜色0的元素丢入栈1
为什么?
当你这样染色的时候,会保证先来的元素优先使用操作字典序更小的栈1
也就是你来的第一个元素它被染成0,就让它进栈1 因为进栈2,是c,这样就通过第一个元素来决定所有和他一样的元素进那个栈了(因为他们必须进同一个栈)
这样也可以解释,当有些元素互相之间没有限制的时候,也总是会优先使用栈1

浙公网安备 33010602011771号