「题解」「JZOJ-4238」纪念碑

题目

\(N\times M\) 的网格中,有 \(P\) 个矩形建筑,求一个最大边长的正方形,使得网格中能找到一个放置正方形的地方,不会与建筑重合。

保证 \(N,M\le 10^6,P\le 40000\)

个人思路(错解)

对于一个建筑 \((a,b)\) ,我们扩展出三个点 \((a,b+1),(a+1,b),(a+1,b+1)\) ,并从这三个点开始寻找最大的那个正方形。

至于如何寻找,使用类似于求最长连续 \(0\) 序列的方法,使用线段树维护。

然而这样的方法很容易说明是错的。

正解

如果有两条在 \(x\) 轴上的扫描线 \(l\)\(r\),表示 \(l\sim r-1\) 之间可以放边长为 \(r-l\) 的正方形。

期望在 \(l\)\(r\) 间放一个边长为 \(r-l+1\) 的矩形。

那么假如我们能在两条扫描线间找到最大空隙 \(ms\)

如果 \(r-l+1\le ms\),那么可以放,接下来 \(r+1\)

如果 \(r-l+1>ms\),便不能放,因此 \(l+1\)。由于 \(l\sim r-1\) 之间可以放边长为 \(r-l\) 的正方形,\(l+1\sim r-1\) 之间便可以放边长为 \(r-l-1\) 的正方形。所以 \(r\) 不用变。

现在问题就是如何求空隙。

显然可以使用线段树,维护最大连续 \(0\)。每个位置的数代表被几个障碍包含。

\(r+1\) 时,加入左边界在 \(x=r\) 上的矩形。

\(l+1\) 时,删除右边界在 \(x=l-1\) 上的矩形。

如何维护最大连续 \(0\)

我们可以维护 \(num,lnum,rnum\) 分别表示最大连续 \(0\),左起最大连续 \(0\),右起最大连续 \(0\)

注意到这道题要支持区间添加与区间删减,且删减区间与添加区间一一对应,再加上一个区间只要有 \(add\) 标记那么最大连续 \(0\) 一定为 \(0\),所以我们可以不下传标记。

代码就不传了,交不了。

posted @ 2020-01-19 18:40  Arextre  阅读(153)  评论(0编辑  收藏  举报