CF2051E 题解

CF2051E 题解

赛时D +7 卡一个多小时,E读错半小时题,比赛完了才发现。估计是今年干出来的最抽象的事情之一。

实际上时间足够也不一定能够在场上做出来E,我感觉这是一道很妙的转化。

题意

每个人有 [ai,bi] 的一个价格,如果商品价格在 [1,ai] ,则这个人会购买并且留下好评;如果价格在 (ai,bi] ,则会购买并且留下差评;其他情形下不会购买。

现在给定一个 k ,最多收到 k 个差评的情况下,制定一个对每个人都一样的价格,使得最后的收益最大。

分析

很显然是不具有单调性的,所以二分价格或者是差评人数之类的是行不通的。

转化1

要明确的两点是:

1.如果最后一个价格没有被任何区间包含,那完全可以把它提高到离他最近的一个 ai ,这样差评不会增加,并且答案是这个差评数下可能的最大值。

2.如果说有一个价格被包含了,不在 a 上,但是不与任何一个 bi 重合,倘若这种情况下给出差评的人不超过 k,那么完全可以把这个价格提高到最近的 bi ,这样给差评的人也不会增加,并且可能是最大的答案。

所以综上所述,最优答案的价格仅可能在端点处取,只用枚举每个端点就可以了

转化2

对于每个价格,又该怎么计算会购买的人数,和会给差评的人数?

会购买的人数很好计算,就是满足 biprice 的人数。

给差评的人数可以抽象成如下问题,给出坐标轴上一个点,问在若干条线段里,有多少条包含了该点,如下图。

img

在所有会购买,也就是右端点在红线之后的线段中(记有 nums 条),不会给出差评的,其实就是所有左端点在红线之后的线段条数(记为 good ),他们的右端点也一定在红线之后,所以包含在了 nums 中。很显然地就可以算出给出差评的人数 bad=numsgood

这一个过程可以直接分别对于 a,b 数组进行排序,不用维护顺序,然后二分查找即可。

posted @   Hanggoash  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
动态线条
动态线条end
点击右上角即可分享
微信分享提示