久未放晴的|

TulipeNoire

园龄:1年10个月粉丝:18关注:17

「JOI Open 2019」三段跳び

题意:

n 个数,q 次查询,每次给出区间 [l,r],求区间内满足以下条件的三元组 (x,y,z)ax+ay+az 的最大值:

  • x<y<z

  • yxzy

做法

考虑可能成为答案的 xy 组成的二元组 (x,y) 是很少的。事实上,这是 O(n) 级别的。我们可以考虑这样的 (x,y) 满足的性质:其必然有 maxi=x+1y1ai<min{ax,ay},否则将一个小的位置换成中间的最大值肯定更优。

而这个条件非常舒服,可以直接单调栈求出这些二元组。具体地,维护一个不降的栈,在访问栈顶时(不一定要成功弹栈)把顶端元素与当前元素组成的二元组加入。这样容易发现不会漏掉任何一个合法的二元组。

得到这 O(n) 个二元组过后怎么快速计算呢?考虑离线下来,按左端点排序,扫描线从右往左扫,不断加入新的二元组,并对某一个后缀进行更新,表示这一个后缀作为 z 可以与 (x,y) 组合。具体地,令 bii 作为 zax+ay 的最大值。那么修改操作就是区间的 bi 对一个值取最大值,查询的是区间 ai+bi 的最大值。这个用线段树怎么做呢?

答案很简单!维护某个区间的 amaxvmax 表示区间内 ai 的最大值与 ai+bi 的最大值,那么当更新的值为 d 时只需要 vmaxmax{vmax,amax+d} 即可。自己稍加思考便可想清楚了。

至此,我们用 O((n+q)logn) 的时间复杂度解决了这个问题。

本文作者:TulipeNoire

本文链接:https://www.cnblogs.com/TulipeNoire/p/18015206/balabala

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   TulipeNoire  阅读(24)  评论(3编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起