神仙题。

首先只有楼房顶有用,然后要斜率递增。

没事干了,上线段树。

肯定要记录区间单调队列的长度 \(len\)。当然把整个能看到的位置都记下来会更方便,然而复杂度就爆了。

顺便再来个区间最大值 \(mx\)

修改是单点,叶子很好搞。询问就是根节点的 \(len\)

难点就在 pushup。

\(mx\) 不管,只看 \(len\)

首先发现,最左边的和最大值都能看到。

pushup 时,首先左边的所有数都仍然能被看到,右边能看到的数的个数和左边的最大值有关,右边留下的只有大于左边最大值的数。

所以我们递归 pushup:

参数有:线段树节点编号 \(o\) 和能看到的数的下界 \(lwr\)(也就是只保留 \(>lwr\) 的数,然后再求看不看得到)

如果 \(mx_o\le lwr\),整个区间都不能看到。

如果 \(a_l>lwr\),那么答案就是 \(len_o\)(能看到的数和没有这个下界没区别)。

如果 \(mx_{lson}\le lwr\),那么左儿子全都没有,递归到右儿子 \(pushup(rson,lwr)\)

否则左儿子的最大值肯定保留了下来,那么右儿子能看到的数与没有下界没有区别,个数是 \(len_o-len_{lson}\)。递归到左儿子 \(pushup(lson,lwr)+len_o-len_{lson}\)

这样 pushup 一次是 \(O(\log n)\)

时间复杂度 \(O(m\log^2n)\)

12-17 04:47