C/C++教程

ABC215F题解

本文主要是介绍ABC215F题解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题面

比赛结束后第一时间想到这个题的解法。
赛时已经想到了这是个二分,我们以此为突破口继续往下走。
考虑 \(\operatorname{check}\) 函数怎么写。我们看这个 \(n\) 是 \(10^7\) 级别的,所以时间复杂度应该是 \(O(n\log_2n)\) ,所以 \(\operatorname{check}\) 函数里面可以遍历整个数组。
那我们先把原数组按照横坐标排个序扔进去做 \(\operatorname{2-pointer}\) 不就可以了么。

我以 \(i\) 为右端点, \(j\) 为左端点,那么什么时候我们可以右移左端点?就是 \(j+1\) 这个点,他的横坐标和 \(i\) 的差值大于等于这个 \(mid\) 。
那么显然如果我在 \(i\) 处做到了 \(j\) ,那么所有 \(i\) 右边的点和 \(j\) 的组合都是合法的,所以这个 \(j\) 他就永远是合法的。
那么我们就可以记录一下已做到的 \(j\) 他的纵坐标的最大值和最小值,和每一个进去的 \(i\) 的纵坐标减一减,如果纵坐标之差要大于等于 \(mid\) ,而横坐标我们已经证明了他的差值必定大于等于 \(mid\) ,那么这个 \(mid\) 就肯定是成立的。

但是这个题,如果只遍历一次那么答案可能会被漏掉,所以还得从右往左遍历一遍,此时 \(j\) 是右端点, \(i\) 是左端点。

这篇关于ABC215F题解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!