如果做了这道题,有可能做出ioi2018 排座位
在一维时,问题就是询问(max(l...r)-min(l...r)=r-l)的段数。
这是个经典的问题。
从(1 o n)进行扫描线。设当前扫到(i)维护两个单调递减/递增栈和两个线段树。
第一个线段树的(j)位置表示(max(j...i)-i+j)的值。
第二个线段树的(j)位置表示(min(j...i)-i+j)的值。
在更新单调栈的时候可以同时更新两个线段树。
查询以当前点为结尾的段数就是查询全局最小值/最小值的个数,可以用线段树简单维护。
或者点-边就可以。
但是二维就不能这么做。
引理:如果把权值为([l,r])的点全部染黑,考虑每个(2*2)的矩形。
当恰好有(4)个黑点个数(=1)的矩形且没有黑点个数为(3)的矩形时符合题目的条件,否则不符合。
必要性显然。
充分性可以考虑:
不是连通块的情况,显然角的个数会(>4)。
一个角可以贡献至少(1)个黑点个数(=1)的(2*2)矩形。
是连通块的情况,这个连通块不能有向内凹的部分,否则会出现黑点个数为(3)的矩形。
画图/感性理解发现这样子是正确的。
(以上纯口胡)
当得到这个结论后,我们可以在扫到(r)时用线段树维护(l)位置([l,r])黑点个数(=1)的矩形+黑点个数为(3)的矩形的个数和。
这是因为黑点个数(=1)的矩形至少有4个。当最小值(=4)时,后面一项肯定为(0)。
在修改时区间+即可。
时间复杂度(O(nmlog_2nm))