容易想到先排除不用过桥的再把过桥的1加上,剩下只需要考虑河边走的距离。
首先考虑k=1的情况,容易发现相当于是一个直线上2n个点选一个点到所有点距离和最小,经典的结论选在中位数。
而k=2的时候,直觉告诉我们可以分组保证选择第一个桥的和第二个桥的排序后具有单调性,考虑一下这个方向。
一开始我想的是按照min排序,这样给定了p1,p2后,如果一个点不在p1,p2之间,那么他的最优方案已经固定了,这时候是满足单调性的。但是如果在p1,p2之间并且他们到达的点也是,那就没有单调性了。
我们于是考虑避免这一种情况的产生,发现只有上下两个点都在p1,p2内才会发生这个情况,这样绝对值就可以去掉,我们希望通过一种排序使得不会出现\(i<j\),满足\(calc(i,p2)<calc(i,p1)\)且\(calc(j,p1)<calc(j,p2)\)。
拆开一下,发现第一个式子等价于\(ai+bi>p1+p2\),第二个等价于\(aj+bj<p1+p2\),这时就显然易见了,我们只需要满足按照\(ai+bi\)排序就能避免这种情况。
现在我们就把问题分成了两个K=1的部分,只需要找到两侧的中位数即可。
中位数有2种方法(大概平衡树也可以用Kth来做但是我不太熟练):
- 线段树二分,很显然,码量略大。
- 用两个堆来实现,一个存前n个元素一个存后n个元素,我们发现是容易维护的。每次新加入之后只可能会出现一次小堆的max>大堆的min,这时候我们取出来再交换一下就行了。
Submissions:
线段树二分:https://uoj.ac/submission/88633
堆:https://uoj.ac/submission/610018