P9732 [CEOI2023] Trade

cxqghzj·2024-04-07 21:27·10 次阅读

P9732 [CEOI2023] Trade

题意#

一个区间,你需要在其中选出一段大于 k 的区间。

使得前 k 大的 si 减去区间 ci 之差最大。

问,价值最大是多少,以及哪些点可以成为被选择的价值最大的区间的前 k 大的点。

Sol#

摆摆摆,颓颓颓。

注意到有决策单调性,考虑怎么证明。

显然,设 fi=maxw(i,j)

有:

w(a,c)+w(b,d)w(a,b)+w(c,d)

注意到 ci 的贡献相同。

w(a,c)+w(b,d)w(a,b)+w(c,d)

即证:

w(a,b)+w(a+1,b+1)w(a,b+1)+w(a+1,b)

注意到对于新加入的 a+1b+1 两个点,在左边显然可以替换掉最小值与次小值,而在右边若最小值与次小值在同一区间,会更劣。

因此我们简单证明了决策单调性。

接下来就好做了,考虑分治,用 l,rL,R 分别表示左端点的区间,与右端点的区间。

每次考虑当前的 mid,暴力枚举所有右端点,找到最优右端点。

递归 l,mid1L,pos,以及 mid+1pos,R 即可。

考虑如何快速计算当前区间的答案。

对于 c 显然是 trivial 的,不再赘述。

考虑如何求出一个区间的前 ksi

这显然可以直接来一发可持久化线段树。

考虑更优秀的做法。

注意到其实每次移动的区间并不多,可以使用类似莫队的方式暴力移动。

为什么移动区间量是 O(nlogn) 的?

可以考虑这样一件事情,对于左端点显然移动次数为 n,对于右端点,对于每个分治区间最劣情况下会跑满,而分治区间的总量显然是 O(nlogn) 级别的。

因此,使用两个对顶堆维护插入删除,总复杂度 O(nlog2n)

考虑第二问,我们在分治的过程中记录下最大的价值,以及当前区间的第 k 大值。

直接使用区间求 min 线段树覆盖,单点查询即可。

总时间复杂度:O(nlog2n+nlogn)

posted @   cxqghzj  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示
目录