查税

来源:互联网 发布:视频配音软件 编辑:程序博客网 时间:2024/04/29 04:28

题目大意及模型转换:

有两种操作,第一种操作是将第x条射线修改,第二种操作是询问第l~r条射线与x=a的交点纵坐标的最大值。射线个数N<=10^5,操作个数M<=3*10^5。每条射线描述包含起点位置、斜率、截距。第一个操作中的起点位置与第二个操作中的"a",是保证非递减的。


暴力:

显然我们可以做到O(1)修改O(N)询问。


分块大法:

这两个时间能不能平衡一下呢?能!都变成O(√N)。我们可以用分块大法,让每块包含√N个元素(实际实现中,是每块√N+1个,这里为了叙述方便)。对于块内元素,我们根据斜率从小到大排序,那么对于排序后编号j<k,一旦当前非递减的"a"坐标超过了交点,那么j永远不会比k优。因此我们可以对于每块维护一个单调队列,保证队列中每两个相邻元素交点大于非递减的"a"。而且交点从小到大。


维护:

对于修改操作,可以使用插入排序对原队列做更改,来维护原队列的有序性。然后直接暴力重构单调队列。对于询问操作,可以看看跨了几个块,对这里的每个块的单调队列进行维护(检测队首与后一个元素的交点是否大于非递减的"a",如果不是,弹出队首)。取出每个块的队首做比较,然后剩余部分用暴力。


复杂度:

容易证明两个操作主要过程都是O(√N)的,有疑问的就是弹出队首那里。有人说重构后可能造成O(N)弹出。我们可以想,最坏情况也需要√N个修改操作,才能换来一次O(N)的询问操作。那么(M/√N)*N=M*√N。所以是没有问题的。


注意:

斜率相同,保留当前更大的。

不要用Pascal,因为跑得慢。

不要尝试快速排序来偷懒,会时间超限。

如果√N个分一块,情况比较难讨论。

如,24,4个为一块可以分成6块。


0 0
原创粉丝点击